Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Prototype should not be inherited #243

Merged
merged 2 commits into from
Oct 8, 2024
Merged

Conversation

gxkl
Copy link
Contributor

@gxkl gxkl commented Oct 8, 2024

Checklist
  • npm test passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)
Description of change

Summary by CodeRabbit

  • New Features

    • Enhanced prototype metadata handling to ensure only own metadata is accessed.
    • Introduced a decorator-based singleton pattern for class instantiation.
  • Bug Fixes

    • Added a test to confirm that prototype properties are not inherited, ensuring expected behavior in class inheritance scenarios.
  • Tests

    • Implemented a new test suite to verify prototype inheritance behavior across various prototype types.
    • Added specific test cases for child prototypes to confirm they do not inherit properties from parent prototypes.

Copy link

coderabbitai bot commented Oct 8, 2024

Walkthrough

The changes introduce a new static method getOwnBooleanMetaData to the MetadataUtil class, enabling retrieval of boolean metadata specific to a class without inheritance. The PrototypeUtil class is updated to use this new method along with getOwnMetaData in several existing methods. A new test suite is added to verify that child prototypes do not inherit properties from parent prototypes, supported by new classes defined in a separate file.

Changes

File Change Summary
core/core-decorator/src/util/MetadataUtil.ts Added method static getOwnBooleanMetaData(metadataKey: MetaDataKey, clazz: EggProtoImplClass): boolean.
core/core-decorator/src/util/PrototypeUtil.ts Updated multiple methods to use MetadataUtil.getOwnBooleanMetaData and MetadataUtil.getOwnMetaData instead of their previous counterparts.
core/core-decorator/test/decorators.test.ts Added a test suite "inherited" and a test case "Prototype should not be inherited" to verify prototype inheritance behavior.
core/core-decorator/test/fixtures/decators/ChildService.ts Introduced classes ParentSingletonProto, ChildSingletonProto, ParentStaticMultiInstanceProto, ChildStaticMultiInstanceProto, ParentDynamicMultiInstanceProto, and ChildDynamicMultiInstanceProto using decorator patterns.

Poem

In the garden where prototypes play,
A rabbit hops in a curious way.
With metadata kept close and tight,
Inheritance shadows fade from sight.
New tests to ensure all is right,
A singleton's charm shines ever so bright! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b6ac8e1 and 71ff945.

📒 Files selected for processing (1)
  • core/core-decorator/test/decorators.test.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/core-decorator/test/decorators.test.ts

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@gxkl gxkl requested a review from killagu October 8, 2024 07:08
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (2)
core/core-decorator/test/fixtures/decators/ChildService.ts (1)

3-4: LGTM: Parent class is correctly defined as a singleton.

The Parent class is properly decorated with @SingletonProto(), ensuring it follows the singleton pattern. The class is correctly exported for use in tests.

Consider adding a comment to explain the purpose of this empty class in the test context. For example:

@SingletonProto()
export class Parent {
  // This empty class is used to test singleton behavior in inheritance
}
core/core-decorator/test/decorators.test.ts (1)

146-149: LGTM! Consider adding more specific assertions

The test case correctly verifies that the Child prototype does not inherit properties from the Parent prototype, which aligns with the PR objective. Good job on keeping the test focused and concise.

To make the test even more robust and informative, consider:

  1. Adding a comment explaining the expected behavior.
  2. Including more specific assertions, such as checking for particular properties.

Here's a suggested enhancement:

it('Prototype should not be inherited', () => {
  // Parent should have prototype properties, while Child should not inherit them
  const parentProps = PrototypeUtil.getProperty(Parent);
  const childProps = PrototypeUtil.getProperty(Child);
  
  assert(parentProps, 'Parent should have prototype properties');
  assert.strictEqual(childProps, undefined, 'Child should not inherit prototype properties');
  
  // Optional: Check for specific properties if known
  // assert(parentProps.name === 'expectedName', 'Parent should have the expected name');
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b6d33dd and e49f816.

📒 Files selected for processing (3)
  • core/core-decorator/src/util/PrototypeUtil.ts (1 hunks)
  • core/core-decorator/test/decorators.test.ts (2 hunks)
  • core/core-decorator/test/fixtures/decators/ChildService.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (3)
core/core-decorator/test/fixtures/decators/ChildService.ts (2)

1-1: LGTM: Import statement is correct.

The import statement for SingletonProto is properly defined using a relative path. This is acceptable for a test fixture.


6-6: Verify the intended behavior of inheriting from a singleton class.

The Child class correctly extends the Parent class, which is marked as a singleton. This setup is likely intended to test singleton behavior in inheritance.

However, inheriting from a singleton class might lead to unexpected behavior. Please verify if this is the intended design for your test case. If it is, consider adding a comment explaining the purpose of this inheritance structure.

To help verify the behavior, you can run the following script:

This will help us understand how the Child class is being used in the tests and confirm if the inheritance from a singleton is intentional.

✅ Verification successful

Inheritance from Singleton Class Verified as Intended

The Child class extends the Parent singleton class as intended. Test cases effectively handle and verify this inheritance without introducing unexpected behaviors.

  • core/core-decorator/test/fixtures/decators/ChildService.ts
  • core/core-decorator/test/util/MetadataUtil.test.ts
  • core/core-decorator/test/decorators.test.ts
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for usage of Child class to understand test context

# Test: Search for Child class usage
rg --type typescript "Child" core/core-decorator/test

Length of output: 88


Script:

#!/bin/bash
# Description: Search for usage of Child class within .ts files in the specified directory

# Search for "Child" in TypeScript files
rg "Child" core/core-decorator/test --include "*.ts" -A 2 -B 2

Length of output: 504


Script:

#!/bin/bash
# Description: Search for usage of Child class within .ts files in the specified directory using find and grep

# Find all .ts files and search for "Child" with context
find core/core-decorator/test -type f -name "*.ts" -exec grep -H -C 2 "Child" {} +

Length of output: 2644

core/core-decorator/test/decorators.test.ts (1)

Line range hint 1-149: Overall assessment: Changes look good with minor improvements suggested

The changes in this file are minimal and focused, aligning well with the PR objective of ensuring that prototypes are not inherited. The new test case effectively verifies this behavior. I've suggested a minor fix for a typo in the import statement and provided some recommendations to enhance the test case further. Once these small adjustments are made, the changes will be in excellent shape.

core/core-decorator/test/decorators.test.ts Outdated Show resolved Hide resolved
core/core-decorator/src/util/PrototypeUtil.ts Show resolved Hide resolved
@gxkl gxkl force-pushed the fix/prototype-inherit branch from e49f816 to b6ac8e1 Compare October 8, 2024 07:45
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (6)
core/core-decorator/src/util/MetadataUtil.ts (1)

31-31: Consider using the class name instead of this in static methods.

While using this in a static context works, it's generally considered a best practice to use the class name instead. This improves code clarity and avoids potential confusion.

Consider updating the line as follows:

-    return !!this.getOwnMetaData(metadataKey, clazz);
+    return !!MetadataUtil.getOwnMetaData(metadataKey, clazz);
🧰 Tools
🪛 Biome

[error] 31-31: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

core/core-decorator/test/decorators.test.ts (2)

154-199: Approve new test suite with a minor suggestion

The new "inherited" test suite is well-structured and effectively verifies that child prototypes do not inherit properties from parent prototypes. It covers SingletonProto, StaticMultiInstanceProto, and DynamicMultiInstanceProto, which is comprehensive.

To improve maintainability, consider extracting the fakeCtx object to a higher scope, possibly as a beforeEach setup, to avoid repetition and make it easier to modify if needed in the future.

Here's a suggested refactor:

describe('inherited', () => {
  let fakeCtx;

  beforeEach(() => {
    fakeCtx = {
      unitPath: 'foo',
      moduleName: '',
    };
  });

  // ... rest of the test cases
});

160-198: Approve test cases with a minor suggestion for consistency

The test cases in the "inherited" suite are thorough and effectively verify that child prototypes do not inherit properties from parent prototypes. The use of strict equality checks is appropriate, and the test descriptions accurately reflect the purpose of each test.

For consistency, consider adding an assertion for isEggMultiInstancePrototype in the dynamic multiInstanceProto test case, similar to the other two test cases.

Add the following assertion at the beginning of the dynamic multiInstanceProto test case:

assert(PrototypeUtil.isEggMultiInstancePrototype(ParentDynamicMultiInstanceProto));
core/core-decorator/test/fixtures/decators/ChildService.ts (3)

6-6: Consider Adding Decorator to 'ChildSingletonProto'

The class ChildSingletonProto extends ParentSingletonProto, which is annotated with @SingletonProto(). If ChildSingletonProto is intended to be a singleton prototype as well, consider adding the @SingletonProto() decorator to ensure consistent behavior and clarity.

Apply this diff to add the decorator:

+@SingletonProto()
 export class ChildSingletonProto extends ParentSingletonProto {}

22-22: Consider Adding Decorator to 'ChildDynamicMultiInstanceProto'

Similarly, ChildDynamicMultiInstanceProto extends ParentDynamicMultiInstanceProto, which is annotated with @MultiInstanceProto(). To maintain consistency and ensure correct instantiation behavior, consider adding the @MultiInstanceProto() decorator to ChildDynamicMultiInstanceProto.

Apply this diff to add the decorator:

+@MultiInstanceProto()
 export class ChildDynamicMultiInstanceProto extends ParentDynamicMultiInstanceProto {}

1-1: Typographical Error in Directory Name

It appears that the directory name decators might be a typo. Consider renaming it to decorators for clarity and to prevent any confusion.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e49f816 and b6ac8e1.

📒 Files selected for processing (4)
  • core/core-decorator/src/util/MetadataUtil.ts (1 hunks)
  • core/core-decorator/src/util/PrototypeUtil.ts (8 hunks)
  • core/core-decorator/test/decorators.test.ts (3 hunks)
  • core/core-decorator/test/fixtures/decators/ChildService.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/core-decorator/src/util/PrototypeUtil.ts
🧰 Additional context used
🪛 Biome
core/core-decorator/src/util/MetadataUtil.ts

[error] 31-31: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (2)
core/core-decorator/src/util/MetadataUtil.ts (2)

30-32: LGTM! New method enhances the API.

The new getOwnBooleanMetaData method is a valuable addition to the MetadataUtil class. It provides a specific method for retrieving boolean metadata, which enhances the API and improves code readability. The implementation is consistent with the class's existing methods and follows the principle of not inheriting metadata from parent classes.

🧰 Tools
🪛 Biome

[error] 31-31: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


Line range hint 1-33: Overall, the changes improve the MetadataUtil class.

The addition of the getOwnBooleanMetaData method enhances the API by providing a specific method for boolean metadata. This improvement aligns well with the existing class structure and functionality. The only suggestion is to use the class name instead of this in the static method for better clarity and adherence to best practices.

🧰 Tools
🪛 Biome

[error] 27-27: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 31-31: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 35-35: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

Copy link
Contributor

@killagu killagu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@killagu killagu merged commit 6e7017a into master Oct 8, 2024
12 checks passed
@killagu killagu deleted the fix/prototype-inherit branch October 8, 2024 08:18
@gxkl
Copy link
Contributor Author

gxkl commented Oct 8, 2024

@coderabbitai coderabbitai bot mentioned this pull request Oct 9, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants