-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
**/__mocks__/** | ||
**/__tests__/** | ||
src |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# jest-serializer | ||
|
||
Module for serializing and deserializing object into memory and disk. By | ||
default, the `v8` implementations are used, but if not present, it defaults to | ||
`JSON` implementation. Both serializers have the advantage of being able to | ||
serialize `Map`, `Set`, `undefined`, `NaN`, etc, although the JSON one does it | ||
through a replacer/reviver. | ||
|
||
## Install | ||
|
||
```sh | ||
$ yarn add jest-serializer | ||
``` | ||
|
||
## API | ||
|
||
Three kinds of API groups are exposed: | ||
|
||
### In-memory serialization: `serialize` and `deserialize` | ||
|
||
This set of functions take or return a `Buffer`. All the process happens in | ||
memory. This is useful when willing to transfer over HTTP, TCP or via UNIX | ||
pipes. | ||
|
||
```javascript | ||
import {serialize, deserialize} from 'jest-serializer'; | ||
|
||
const myObject = { | ||
foo: 'bar', | ||
baz: [0, true, '2', [], {}], | ||
}; | ||
|
||
const buffer = serialize(myObject); | ||
const myCopyObject = deserialize(buffer); | ||
``` | ||
|
||
### Synchronous persistent filesystem: `readFileSync` and `writeFileSync` | ||
|
||
This set of functions allow to send to disk a serialization result and retrieve | ||
it back, in a synchronous way. It mimics the `fs` API so it looks familiar. | ||
|
||
```javascript | ||
import {readFileSync, writeFileSync} from 'jest-serializer'; | ||
|
||
const myObject = { | ||
foo: 'bar', | ||
baz: [0, true, '2', [], {}], | ||
}; | ||
|
||
const myFile = '/tmp/obj'; | ||
|
||
writeFileSync(myFile, myObject); | ||
const myCopyObject = readFileSync(myFile); | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"name": "jest-serializer", | ||
"version": "22.3.0", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/facebook/jest.git" | ||
}, | ||
"license": "MIT", | ||
"main": "build/index.js" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* 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. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
import prettyFormat from 'pretty-format'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right! good catch! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, actually no 😅. There's no way you can develop There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. 👍 |
||
|
||
import fs from 'fs'; | ||
import os from 'os'; | ||
import path from 'path'; | ||
import v8 from 'v8'; | ||
|
||
import serializer from '..'; | ||
|
||
const v8s = [ | ||
{ | ||
deserialize: v8.deserialize, | ||
serialize: v8.serialize, | ||
}, | ||
{ | ||
deserialize: undefined, | ||
serialize: undefined, | ||
}, | ||
]; | ||
|
||
const objs = [ | ||
3, | ||
null, | ||
[0, true, '2', [3.14, {}, null]], | ||
{key1: 'foo', key2: 'bar', key3: {array: [null, {}]}}, | ||
{minusInf: -Infinity, nan: NaN, plusInf: +Infinity}, | ||
{date: new Date(1234567890), re: /foo/gi}, | ||
{map: new Map([[NaN, 4], [undefined, 'm']]), set: new Set([undefined, NaN])}, | ||
{buf: Buffer.from([0, 255, 127])}, | ||
]; | ||
|
||
const file = path.join(os.tmpdir(), '__jest-serialize-test__'); | ||
|
||
afterEach(() => { | ||
try { | ||
fs.unlinkSync(file); | ||
} catch (err) { | ||
// Do nothing if file does not exist. | ||
} | ||
}); | ||
|
||
// We execute the same suite of tests over multiple objects ("objs") and over | ||
// multiple mocks of the V8 object ("v8s") so that we verify that all possible | ||
// encodings and cases work. | ||
v8s.forEach((mockV8, i) => { | ||
describe('Using V8 implementation ' + i, () => { | ||
beforeEach(() => { | ||
v8.serialize = mockV8.serialize; | ||
v8.deserialize = mockV8.deserialize; | ||
}); | ||
|
||
it('throws the error with an invalid serialization', () => { | ||
// No chance this is a valid serialization, neither in JSON nor V8. | ||
const invalidBuffer = Buffer.from([0, 85, 170, 255]); | ||
|
||
fs.writeFileSync(file, invalidBuffer); | ||
|
||
expect(() => serializer.deserialize(invalidBuffer)).toThrow(); | ||
expect(() => serializer.readFileSync(file)).toThrow(); | ||
}); | ||
|
||
objs.forEach((obj, i) => { | ||
describe('Object ' + i, () => { | ||
it('serializes/deserializes in memory', () => { | ||
const buf = serializer.serialize(obj); | ||
|
||
expect(buf).toBeInstanceOf(Buffer); | ||
|
||
expect(prettyFormat(serializer.deserialize(buf))).toEqual( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice workaround on different different contexts ^^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
prettyFormat(obj), | ||
); | ||
}); | ||
|
||
it('serializes/deserializes in disk', () => { | ||
serializer.writeFileSync(file, obj); | ||
|
||
expect(prettyFormat(serializer.readFileSync(file))).toEqual( | ||
prettyFormat(obj), | ||
); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some Flow maybe?
There was a problem hiding this comment.
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)