Skip to content

Conversation

puskin
Copy link
Contributor

@puskin puskin commented Aug 29, 2024

Fixes: #50399

Took heavy inspiration from #53415 , trying to push it to the finish line 🚀

On top of it, I took the liberty of:

  1. refactor the code a bit
  2. wrote more documentation
  3. added more tests and restructured old ones
  4. implement previously reported comments / suggestions
Notable change

Introducing experimental assert.partialDeepStrictEqual

Sometimes, when writing test, we want to validate that some specific properties
are present, and the mere presence of additional keys are not exactly relevant
for that specific test. For this use case, we can now use
assert.partialDeepStrictEqual, which should be familiar to those already using
assert.deepStrictEqual, with the main difference that it does not require all
properties in the actual parameter to be present in the expected parameter.

Here are a few examples of usage:

assert.partialDeepStrictEqual(
  { a: 1, b: 2, c: 3 },
  { a: 1, b: 2 },
);

assert.partialDeepStrictEqual(
  [1, 2, 3, 4],
  [2, 3],
);

assert.partialDeepStrictEqual(
  { a: { b: { c: 1, d: 2 } }, e: 3 },
  { a: { b: { c: 1 } } },
);

assert.partialDeepStrictEqual(
  { a: { b: { c: 1, d: 2 } }, e: 3 },
  { a: { b: { c: 1 } } },
);

assert.partialDeepStrictEqual(
  new Set([{ a: 1 }, { b: 1 }]),
  new Set([{ a: 1 }]),
);

assert.partialDeepStrictEqual(
  { a: new Set([{ a: 1 }, { b: 1 }]), b: new Map(), c: [1, 2, 3] },
  { a: new Set([{ a: 1 }]), c: [2] },
);

Co-Authored-By: Cristian Barlutiu

@nodejs-github-bot nodejs-github-bot added assert Issues and PRs related to the assert subsystem. needs-ci PRs that need a full CI run. labels Aug 29, 2024
@puskin puskin force-pushed the assert-deep-match-and-includes branch from 466c2f0 to c0a58e2 Compare August 29, 2024 12:28
Copy link

codecov bot commented Aug 29, 2024

Codecov Report

Attention: Patch coverage is 95.73460% with 9 lines in your changes missing coverage. Please review.

Project coverage is 88.50%. Comparing base (4f88179) to head (8722fbd).
Report is 463 commits behind head on main.

Files with missing lines Patch % Lines
lib/assert.js 95.71% 8 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #54630      +/-   ##
==========================================
+ Coverage   88.23%   88.50%   +0.26%     
==========================================
  Files         652      653       +1     
  Lines      183920   187937    +4017     
  Branches    35863    36233     +370     
==========================================
+ Hits       162286   166333    +4047     
+ Misses      14913    14827      -86     
- Partials     6721     6777      +56     
Files with missing lines Coverage Δ
lib/internal/test_runner/test.js 96.97% <100.00%> (+0.03%) ⬆️
lib/assert.js 99.01% <95.71%> (-0.86%) ⬇️

... and 289 files with indirect coverage changes

---- 🚨 Try these New Features:

@puskin puskin force-pushed the assert-deep-match-and-includes branch from c0a58e2 to 04e92f0 Compare August 29, 2024 14:20
@avivkeller avivkeller added semver-minor PRs that contain new features and should be released in the next minor version. notable-change PRs with changes that should be highlighted in changelogs. labels Aug 29, 2024
Copy link
Contributor

The notable-change PRs with changes that should be highlighted in changelogs. label has been added by @redyetidev.

Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section.

@avivkeller
Copy link
Member

This PR adds new functionality, hence semver-minor

This PR's new functionality (IMO) is notable-change

@puskin puskin force-pushed the assert-deep-match-and-includes branch from 04e92f0 to 0ee83d4 Compare August 29, 2024 16:04
// AssertionError
```

## `assert.includes(actual, expected[, message])`
Copy link
Member

Choose a reason for hiding this comment

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

I'm less convinced that this one is useful. Why not just simply use assert(actual.includes(expected))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jasnell I just followed the most "approved" comment in the original PR and implemented it :)

#50399 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @jasnell and don't think this should be implemented. Let us concentrate on the partial inclusion. If anyone would ever ask for something else, we can still implement more.

@puskin
Copy link
Contributor Author

puskin commented Sep 10, 2024

is there any way we can push this forward? ar far as I know there is a little bit of people waiting for this and no clear consensus on the naming convention :)

@jasnell
Copy link
Member

jasnell commented Sep 10, 2024

I still have concerns about whether we need everything in this PR but would very much like others to weigh in. @nodejs/test_runner @nodejs/assert ... anyone have thoughts?

@ljharb
Copy link
Member

ljharb commented Sep 10, 2024

re naming, I definitely think the term "match" should be reserved for regexes.

if the only difference between these new methods and deepEqual etc is that they allow extra properties, then perhaps it would make more sense as an option to the existing methods rather than entirely new ones?

@puskin
Copy link
Contributor Author

puskin commented Sep 10, 2024

@ljharb the discussion where the "option" was discarded in favor of the new API started from this comment: #50399 (comment)

@puskin
Copy link
Contributor Author

puskin commented Sep 10, 2024

other method names we could consider:

assert.subsetEqual() assert.containsSubset() assert.partialEqual()

@ljharb
Copy link
Member

ljharb commented Sep 10, 2024

To clarify, the current proposal takes an "actual" and "expected", and it checks that every property on expected is deepEqual to the same property on actual? Are nested objects on expected checked using full or partial equality?

What about if I want to assert that a property is not present? is there a way to represent "never"?

@puskin
Copy link
Contributor Author

puskin commented Sep 10, 2024

good questions!

yes, this test will pass:

      {
        description: 'compares two deeply nested objects with partial equality',
        actual: { a: {nested: {property: true, some: 'other'}} },
        expected: { a: {nested: {property: true}} },
      },

and no, there is no way to check "not inclusion" , just if an object is a subset of another

@ljharb
Copy link
Member

ljharb commented Sep 10, 2024

assert.subsetDeepEqual? (also shouldn't the default be strict, and the extra one be "Loose"?)

@puskin
Copy link
Contributor Author

puskin commented Sep 10, 2024

that would deviate from the already present implementations, like deepStrictEqual and deepEqual

Copy link
Member

@MoLow MoLow left a comment

Choose a reason for hiding this comment

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

implementation LGTM, I agree with the concerns on naming, lets change the name so this can land?
+1 for partialDeepEqual

@avivkeller
Copy link
Member

+1 for partialDeepEqual

Agreed. Also, should this have a notPartialDeepEqual inverse?

@puskin puskin force-pushed the assert-deep-match-and-includes branch 2 times, most recently from ab7e68e to 3d52d4b Compare September 11, 2024 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assert Issues and PRs related to the assert subsystem. author ready PRs that have at least one approval, no pending requests for changes, and a CI started. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: assert.matchObject