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

feat!: detect duplicate test cases #17955

Merged
merged 16 commits into from Jan 20, 2024
Merged

Conversation

bmish
Copy link
Sponsor Member

@bmish bmish commented Jan 4, 2024

Prerequisites checklist

What is the purpose of this pull request? (put an "X" next to an item)

[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[x] Add something to the core
[ ] Other, please explain:

What changes did you make? (Give an overview)

Fixes #15104, alongside:

Link to this feature in the RFC:

Inspired by:

Is there anything you'd like reviewers to focus on?

Are we okay with adding this isSerializable() function? Surprisingly, I couldn't find any third-party library that offers it. I had an alternative approach visible in b400d1e that simply checked for the presence of any properties that might not be serializable, but this could have false negatives. See discussion in #17955 (comment).

TODO:

  • Add more tests to rule tester
    • Unserializable properties
    • Varying object key ordering is ignored
  • Fix duplicate rule tests found by this

@eslint-github-bot eslint-github-bot bot added breaking This change is backwards-incompatible feature This change adds a new feature to ESLint labels Jan 4, 2024
Copy link

netlify bot commented Jan 4, 2024

Deploy Preview for docs-eslint canceled.

Name Link
🔨 Latest commit 7a34ae7
🔍 Latest deploy log https://app.netlify.com/sites/docs-eslint/deploys/65abe639bde90b0008ae4c77

@bmish bmish mentioned this pull request Jan 4, 2024
10 tasks
@nzakas
Copy link
Member

nzakas commented Jan 11, 2024

We are waiting on #17654 for this, correct?

@bmish
Copy link
Sponsor Member Author

bmish commented Jan 11, 2024

No I think we can treat them as independent.

* main:
  chore: Split Docs CI from core CI (eslint#17897)
  fix: Ensure config keys are printed for config errors (eslint#17980)
  chore: delete relative-module-resolver.js (eslint#17981)
  docs: migration guide entry for `no-inner-declarations` (eslint#17977)
  docs: Update README
  feat: maintain latest ecma version in ESLint (eslint#17958)
  feat!: no-inner-declaration new default behaviour and option (eslint#17885)
  feat: add `no-useless-assignment` rule (eslint#17625)
  fix: `no-misleading-character-class` edge cases with granular errors (eslint#17970)
  feat: `no-misleading-character-class` granular errors (eslint#17515)
  docs: fix number of code-path events on custom rules page (eslint#17969)
  docs: reorder entries in v9 migration guide (eslint#17967)
  fix!: handle `--output-file` for empty output when saving to disk (eslint#17957)
* main:
  docs: Update note about ECMAScript support (eslint#17991)
  chore: update `markdownlint` to `v0.33.0` (eslint#17995)
  docs: Update release blog post template (eslint#17994)
  docs: Add sections on non-npm plugin configuration (eslint#17984)
  9.0.0-alpha.1
  Build: changelog update for 9.0.0-alpha.1
  chore: package.json update for @eslint/js release
@bmish bmish marked this pull request as ready for review January 16, 2024 22:24
@bmish bmish requested a review from a team as a code owner January 16, 2024 22:24
@bmish
Copy link
Sponsor Member Author

bmish commented Jan 16, 2024

This is ready for review.

Copy link
Member

@aladdin-add aladdin-add left a comment

Choose a reason for hiding this comment

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

need to add it to the migration guide, otherwise LGTM! 👍

tests/lib/rules/no-misleading-character-class.js Outdated Show resolved Hide resolved
* @private
*/
function checkDuplicateTestCase(item, seenTestCases) {
if ((Array.isArray(item.options) && item.options.some(i => typeof i === "object")) || item.settings || item.languageOptions?.parser || item.languageOptions?.parserOptions || item.plugins) {
Copy link
Member

Choose a reason for hiding this comment

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

there is a room to improve it, but I think it's fine to just check these properties 👍 - as it's described in the rfc.

Copy link
Sponsor Member Author

@bmish bmish Jan 17, 2024

Choose a reason for hiding this comment

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

It's a start.

However, I would love it if I could replace this bail-out logic with a simple function call to see if a given object is serializable. Surprisingly, I haven't found a third-party library to do this. Another option is to try to piece together such a function based on StackOverflow snippets (https://stackoverflow.com/questions/30579940/reliable-way-to-check-if-objects-is-serializable-in-) etc and add unit tests for it. Thoughts?

It might be best to solve this the right way now (in a way that avoids a lot of false negatives) since changing this later could be a breaking change.

Copy link
Member

Choose a reason for hiding this comment

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

IMHO, it's not worth adding a new dependency: rule tester is shipped with eslint, but most eslint users don't really use it. A simple implementation to cover 90%+ cases is good enough for me. 😄

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

I went ahead and added a isSerializable() function which uses only the tiny lodash.isplainobject as a dependency. While the previous approach could have been sufficient as you mentioned, this new approach is a lot more robust (no false negatives) and the code is cleaner.

@nzakas
Copy link
Member

nzakas commented Jan 17, 2024

@christian-bromann looks like our browser tests are failing again, can you take a look?

@christian-bromann
Copy link
Contributor

@nzakas on it

@christian-bromann
Copy link
Contributor

looks like our browser tests are failing again, can you take a look?

@nzakas @bmish I've discovered a performance regression with the recent release which forced me to find the culprit which I did successfully. The browser tests should run much faster now and should be more reliable too. Please re-trigger the build and the fix should be picked up automatically.

@mdjermanovic mdjermanovic added the accepted There is consensus among the team that this change meets the criteria for inclusion label Jan 18, 2024
@mdjermanovic
Copy link
Member

Please re-trigger the build and the fix should be picked up automatically.

It works now, thanks!

Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

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

LGTM. Would like @mdjermanovic to review before merging.

Comment on lines 25 to 36
/**
* Check if an object is serializable.
* Functions or objects like RegExp cannot be serialized by JSON.stringify().
* Inspired by: https://stackoverflow.com/questions/30579940/reliable-way-to-check-if-objects-is-serializable-in-javascript
* @param {any} obj the object
* @returns {boolean} true if the object is serializable
*/
function isSerializable(obj) {
if (!isSerializablePrimitiveOrPlainObject(obj)) {
return false;
}
for (const property in obj) {
Copy link
Member

Choose a reason for hiding this comment

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

Does "object" mean that this function expects only objects? If that's not the case, then it might be better to rename obj to val to clarify that it accepts any value, and also do for-in only on objects so that it doesn't, for example, iterate over string characters (currently, for string test cases, it calls isSerializablePrimitiveOrPlainObject for each character of the string).

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

Good point, changed to val, and only looping for objects.

Copy link
Member

@mdjermanovic mdjermanovic left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion breaking This change is backwards-incompatible feature This change adds a new feature to ESLint
Projects
Status: Complete
Development

Successfully merging this pull request may close these issues.

Change Request: Stricter rule test validation
6 participants