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

Add jest-serializer module #5609

Merged
merged 3 commits into from
Feb 19, 2018
Merged

Add jest-serializer module #5609

merged 3 commits into from
Feb 19, 2018

Conversation

mjesun
Copy link
Contributor

@mjesun mjesun commented Feb 19, 2018

This PR adds a new jest-serializer module, which combines V8 and JSON serializers, with APIs to serialize/deserialize in memory and/or from disk, either synchronously or asynchronously, which can later be used in jest-haste-map (as shown on the PR), or in jest-worker, to communicate between parent and child processes.

Tests were added to it covering all APIs with a variety of objects.

Resolves #5575

pipes.

```javascript
import serializer from 'jest-serializer';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Destructuring maybe?

import {serialize, deserialize} from 'jest-serializer';

* Copyright (c) 2018-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Some Flow maybe?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, pardon this is a test (so it's not necessary to flow it, but I like to mix these)

"license": "MIT",
"main": "build/index.js",
"dependencies": {
"merge-stream": "^1.0.1"
Copy link
Contributor

Choose a reason for hiding this comment

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

Where is used this dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nowhere 😳I just copy-pasted the jest-worker one and forgot to remove.

@cpojer
Copy link
Member

cpojer commented Feb 19, 2018

I like this but I have two high-level comments:

  • Do we really need all the fs APIs in there? If yes, do we really need the async versions or can we just expose the sync ones? Then users can compose the async ones themselves and the sync ones are available. Mainly asking because the API surface would be smaller. Even better would be to only expose serialize/deserialize but I can see how the helpers are useful.
  • This now creates an interface that has different behaviors based on the node version, without warnings. I don't think we can merge it like this. For example, on node 8, serializing a Map will work whereas on node 6 it won't work. I'd like the JSON implementation to keep working or at least throwing an error if it can't work on that version of node. I think using reviver/serializer is fine but see https://github.com/cognitect/transit-js for other types of serializers.

@mjesun
Copy link
Contributor Author

mjesun commented Feb 19, 2018

  • I would prefer to keep both fs versions, because they are mutually exclusive (you cannot make the async work as sync and vice versa), but I'm fine removing one of them.

  • You are right regarding V8 vs JSON serialization. I will add a reviver that can handle: undefined, NaN, Infinity, -Infinity, Date, RegExp, Set, Map and Buffer. I think we'll be in a good position with these types.

@cpojer
Copy link
Member

cpojer commented Feb 19, 2018

Let's remove the async ones until we need them. What I meant you can manually call fs.writeFile(file, serialize(data), callback) and that's fine.

: JSON.parse(fs.readFileSync(file, 'utf8'));
}

export function writeFileSync(file: Path, content: any) {
Copy link
Member

Choose a reason for hiding this comment

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

can you call this filePath?


// Asynchronous filesystem functions.

export function readFile(file: Path, callback: IOCallback) {
Copy link
Member

@SimenB SimenB Feb 19, 2018

Choose a reason for hiding this comment

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

if we expose an async API, I'd prefer it to be promise instead of callback based

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just killed the async one 😜. But you are right; it should have been Promise based. I just followed the standard Node JS format.

The reason for killing it is because we don't really need it anywhere: neither in jest-haste-map, nor in jest-worker (coming soon), nor in Metro, where we will use this module as well.

@codecov-io
Copy link

Codecov Report

Merging #5609 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5609      +/-   ##
==========================================
+ Coverage   60.63%   60.64%   +<.01%     
==========================================
  Files         213      214       +1     
  Lines        7311     7310       -1     
  Branches        3        4       +1     
==========================================
  Hits         4433     4433              
+ Misses       2877     2876       -1     
  Partials        1        1
Impacted Files Coverage Δ
packages/jest-cli/src/search_source.js 45.07% <ø> (ø) ⬆️
packages/jest-haste-map/src/index.js 97.16% <100%> (+0.85%) ⬆️
packages/jest-serializer/src/index.js 92.85% <100%> (ø)
.../src/legacy_code_todo_rewrite/jest_adapter_init.js 0% <0%> (ø) ⬆️
packages/jest-config/src/normalize.js 93.4% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f5879c0...c715d6f. Read the comment docs.

Copy link
Collaborator

@thymikee thymikee left a comment

Choose a reason for hiding this comment

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

LGTM


'use strict';

import prettyFormat from 'pretty-format';
Copy link
Collaborator

Choose a reason for hiding this comment

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

pretty-format should go to devDependencies now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right! good catch!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, actually no 😅. There's no way you can develop jest without having pretty-format (yarn complained when trying to add it, and it ended up adding it to the root package.json instead of the child one).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ahh, I thought about this because it's going to be a standalone package, but then again, it's still inside a workspace monorepo. 👍


expect(buf).toBeInstanceOf(Buffer);

expect(prettyFormat(serializer.deserialize(buf))).toEqual(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice workaround on different different contexts ^^

Copy link
Contributor Author

Choose a reason for hiding this comment

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

☺️

return {[JS_TYPE]: 'm', [JS_VALUE]: Array.from(value)};

case Buffer:
return {[JS_TYPE]: 'b', [JS_VALUE]: value.toString('latin1')};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any particular reason behind latin1 encoding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's the most optimal way of converting a buffer into a string. Other candidates would be an array (way too long to decode), a UTF-8 string (but not all sequences you might find are valid sequences), or a hex one (which is going to longer or at most as equal as a latin1 string) 🙂

@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create a jest-serialize package that uses either v8 serialize or JSON
7 participants