-
-
Notifications
You must be signed in to change notification settings - Fork 36
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
Fix merging of Buffer
objects
#100
base: main
Are you sure you want to change the base?
Conversation
Previously, if you attempted to `build`/`create` an object whose properties contained `Buffer`s, they would be converted from the native `Buffer` type into an array (and thus creating an _incorrect_ value). This is caused by the use of lodash's `merge` implementation (see lodash/lodash#2964). The recommended solution from the lodash project is to define a merge `customizer` to specifically handle this situation, which is what we do here.
Having the same problem with |
fix: pull recent changes and support TypedArray instances as well as Buffer
@rakeshpetit and I are going to see if we can write some unit tests to go along with this PR, and verify that this fix is both needed and effective. |
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.
Thanks for this PR!
Could we add a test to prevent future regressions? Here's what I wrote when testing this change:
// lib/__tests__/merge-params.test.ts
it('does not convert array-like objects to arrays when merging', () => {
type User = {
a: ArrayBuffer;
b: Buffer;
c: Uint8Array;
d: Float32Array;
e: Int8Array;
f: DataView;
g: string[];
nested: {
a: ArrayBuffer;
b: Buffer;
c: Uint8Array;
d: Float32Array;
e: Int8Array;
f: DataView;
g: string[];
};
};
const userFactory = Factory.define<User>(() => ({
a: new ArrayBuffer(5),
b: Buffer.from('hello'),
c: new Uint8Array(5),
d: new Float32Array(5),
e: new Int8Array(5),
f: new DataView(new ArrayBuffer(5)),
g: ['hello'],
nested: {
a: new ArrayBuffer(5),
b: Buffer.from('hello'),
c: new Uint8Array(5),
d: new Float32Array(5),
e: new Int8Array(5),
f: new DataView(new ArrayBuffer(5)),
g: ['hello'],
},
}));
const user = userFactory.build({
a: new ArrayBuffer(5),
b: Buffer.from('hello'),
c: new Uint8Array(5),
d: new Float32Array(5),
e: new Int8Array(5),
f: new DataView(new ArrayBuffer(5)),
g: ['hello'],
nested: {
a: new ArrayBuffer(5),
b: Buffer.from('hello'),
c: new Uint8Array(5),
d: new Float32Array(5),
e: new Int8Array(5),
f: new DataView(new ArrayBuffer(5)),
g: ['hello'],
},
});
expect(user.a).toBeInstanceOf(ArrayBuffer);
expect(user.b).toBeInstanceOf(Buffer);
expect(user.c).toBeInstanceOf(Uint8Array);
expect(user.d).toBeInstanceOf(Float32Array);
expect(user.e).toBeInstanceOf(Int8Array);
expect(user.f).toBeInstanceOf(DataView);
expect(Array.isArray(user.g)).toBe(true);
expect(user.nested.a).toBeInstanceOf(ArrayBuffer);
expect(user.nested.b).toBeInstanceOf(Buffer);
expect(user.nested.c).toBeInstanceOf(Uint8Array);
expect(user.nested.d).toBeInstanceOf(Float32Array);
expect(user.nested.e).toBeInstanceOf(Int8Array);
expect(user.nested.f).toBeInstanceOf(DataView);
expect(Array.isArray(user.nested.g)).toBe(true);
});
if (Array.isArray(srcVal) || ArrayBuffer.isView(srcVal)) { | ||
return srcVal; |
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.
Great solution. To help with future maintenance, I'd love to add a comment here
if (Array.isArray(srcVal) || ArrayBuffer.isView(srcVal)) { | |
return srcVal; | |
if (Array.isArray(srcVal) || ArrayBuffer.isView(srcVal)) { | |
// don't try to merge arrays or subclasses of TypedArray | |
// ArrayBuffer.isView() matches Buffer, Uint8Array, Float32Array, etc. | |
return srcVal; |
Previously, if you attempted to
build
/create
an object whose properties containedBuffer
s, they would be converted from the nativeBuffer
type into an array (and thus creating an incorrect value). This is caused by the use of lodash'smerge
implementation (see lodash/lodash#2964).The recommended solution from the lodash project is to define a merge
customizer
to specifically handle this situation, which is what we do here.