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

Feature/rename #4

Merged
merged 11 commits into from Jan 23, 2019
Merged

Feature/rename #4

merged 11 commits into from Jan 23, 2019

Conversation

DaQuirm
Copy link
Contributor

@DaQuirm DaQuirm commented Jan 14, 2019

This adds rename/renameSync as described in:

http://man7.org/linux/man-pages/man2/rename.2.html

@DaQuirm DaQuirm requested review from AviVahl and removed request for AviVahl January 14, 2019 13:46
@DaQuirm DaQuirm force-pushed the feature/rename branch 4 times, most recently from 5ffb580 to df47be5 Compare January 14, 2019 15:37
Copy link
Collaborator

@AviVahl AviVahl left a comment

Choose a reason for hiding this comment

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

Awesome work. I'm aware changing the base APIs requires a bit more work than the extended ones.
I hope it wasn't too painful having to find/edit all these integration points (I believe you covered them all, so kudos!).

Also nice to see that you've found your way around the memory fs! Great work there.

Several points that came to mind during the review:

  • describe could be separated into "renaming files" and "renaming directories", to be more consistent with other describes. Directory describe would probably contain more tests, due to behaviors with existing target directory (empty or not).
  • tests currently use sourcePath. using sourceFilePath / sourceDirectoryPath might make following what's being renamed easier. though if describes are separated, this point might be redundant.
  • after sync tests are reviewed/refactored/ready, please create the async base contract version as well. anyone creating an async-only fs (remote one, for example) should have his rename implementation tested too.
  • should memory's rename touch mtime/birthtime?
  • see additional comments next to relevant source lines

packages/test-kit/src/sync-base-fs-contract.ts Outdated Show resolved Hide resolved
expect(() => fs.renameSync(sourcePath, join(tempDirectoryPath, 'dir', 'file2'))).to.throw('ENOENT')
})

it('doesn\'t throw if destination path already exists for copying a directory over a non-existing directory', () => { //tslint:disable-line
Copy link
Collaborator

Choose a reason for hiding this comment

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

the test description is a bit confusing. we don't usually test that stuff don't happen. the "not throwing" aspect is covered by many tests calling renameSync on various fixtures. If those calls threw, those tests would have failed. Checking it separately feels unneeded.

the expect in this test is covered by the 'moves a directory' test, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This testing case defines the desired behavior, other tests may be changed, refactored or even removed, I feel it's good to be explicit about these things but I also understand how it might seem odd. The best way I'd say is to express such things with types whenever possible.

packages/memory/src/memory-fs.ts Outdated Show resolved Hide resolved
packages/test-kit/src/sync-base-fs-contract.ts Outdated Show resolved Hide resolved
packages/test-kit/src/sync-base-fs-contract.ts Outdated Show resolved Hide resolved
packages/memory/src/memory-fs.ts Show resolved Hide resolved
packages/types/src/base-api.ts Outdated Show resolved Hide resolved
@DaQuirm
Copy link
Contributor Author

DaQuirm commented Jan 17, 2019

First of all, that's a very thorough and insightful review, good job! 👍

  • describe could be separated into "renaming files" and "renaming directories", to be more consistent with other describes. Directory describe would probably contain more tests, due to behaviors with existing target directory (empty or not).

I'd suggest using a separate describe for the directories, since a fair share of tests verifies behavior common for both files and directories (e.g. that the existence of containing directories is checked).

Concerning directory copying: a few relevant cases could not be tested adequately without writing platform-dependent tests. The reason is that there are still discrepancies in the way nodejs rename works on different platforms. Consider this open issue for instance: nodejs/node#21957

  • tests currently use sourcePath. using sourceFilePath / sourceDirectoryPath might make following what's being renamed easier. though if describes are separated, this point might be redundant.

That's a good point, it makes things clearer! 👍

  • after sync tests are reviewed/refactored/ready, please create the async base contract version as well. anyone creating an async-only fs (remote one, for example) should have his rename implementation tested too.

Oh, I didn't think about that option! What do you think about making the test code polymorphic in respect of whether it's run synchronously or asynchronously?

  • should memory's rename touch mtime/birthtime?

It definitely should, totally missed that!

  • see additional comments next to relevant source lines

Will do!

@AviVahl
Copy link
Collaborator

AviVahl commented Jan 22, 2019

Fixes look good. Please check why tests are failing.

I'm not sure how I feel about the new .sequence() matcher. It feels a bit duplicate. We could rename lastEvent(), and change it to accept either a single event or array of events:

Nice pattern for this:

public async validateEvents(expectedEvents: IWatchEvent | IWatchEvent[]): Promise<void> {
    const { capturedEvents } = this
    if (!Array.isArray(expectedEvents)) {
        expectedEvents = [ expectedEvents ]
    }
    // typescript knows expectedEvents is an IWatchEvent[] at this point in flow
    ...
}

timeout might need to be adjusted (multiplied by expectedEvents.length) and so on.

Regarding the non-consistent cross-platform behavior:

  • If all platforms throw an error, but different codes, avoid checking it for the specific code. just verify it throws.
  • we could add a boolean flag to the contract test input to mark specific platforms/fs which we know are diverging. That flag can be used to skip problematic tests.
  • If some behavior is too problematic to test cross-platform, skip that test and put a comment explaining why.

Other than that, once you finish cleaning up and everything's green, let me know and I'll squash+release.

@DaQuirm
Copy link
Contributor Author

DaQuirm commented Jan 23, 2019

Okay, watch events proved to be too different to test without resorting to platform-aware code so I'm reverting the test and the changes to WatchEventsValidator. This should make the builds green again 💚

@AviVahl
Copy link
Collaborator

AviVahl commented Jan 23, 2019

Great work!

@DaQuirm DaQuirm merged commit be9a3a3 into master Jan 23, 2019
@DaQuirm DaQuirm deleted the feature/rename branch January 23, 2019 11:24
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.

None yet

2 participants