diff --git a/packages/bolt-connection/src/bolt/transformer.js b/packages/bolt-connection/src/bolt/transformer.js index 485c157dd..726f05fe7 100644 --- a/packages/bolt-connection/src/bolt/transformer.js +++ b/packages/bolt-connection/src/bolt/transformer.js @@ -18,6 +18,9 @@ */ import { structure } from '../packstream' +import { internal } from 'neo4j-driver-core' + +const { util } = internal /** * Class responsible for applying the expected {@link TypeTransformer} to @@ -43,11 +46,15 @@ export default class Transformer { * @returns {|structure.Structure} The driver object or the structure if the transformer was not found. */ fromStructure (struct) { - if (struct instanceof structure.Structure && this._transformersPerSignature.has(struct.signature)) { - const { fromStructure } = this._transformersPerSignature.get(struct.signature) - return fromStructure(struct) + try { + if (struct instanceof structure.Structure && this._transformersPerSignature.has(struct.signature)) { + const { fromStructure } = this._transformersPerSignature.get(struct.signature) + return fromStructure(struct) + } + return struct + } catch (error) { + return util.createBrokenObject(error) } - return struct } /** diff --git a/packages/bolt-connection/test/bolt/__snapshots__/bolt-protocol-v5x0.test.js.snap b/packages/bolt-connection/test/bolt/__snapshots__/bolt-protocol-v5x0.test.js.snap index 4d3877736..b379fa05c 100644 --- a/packages/bolt-connection/test/bolt/__snapshots__/bolt-protocol-v5x0.test.js.snap +++ b/packages/bolt-connection/test/bolt/__snapshots__/bolt-protocol-v5x0.test.js.snap @@ -36,9 +36,9 @@ exports[`#unit BoltProtocolV5x0 .unpack() should not unpack with wrong size (Nod exports[`#unit BoltProtocolV5x0 .unpack() should not unpack with wrong size (Node with more fields) 1`] = `"Wrong struct size for Node, expected 4 but was 5"`; -exports[`#unit BoltProtocolV5x0 .unpack() should not unpack with wrong size (Path with less fields) 1`] = `"Wrong struct size for Node, expected 4 but was 3"`; +exports[`#unit BoltProtocolV5x0 .unpack() should not unpack with wrong size (Path with less fields) 1`] = `"Wrong struct size for Path, expected 3 but was 2"`; -exports[`#unit BoltProtocolV5x0 .unpack() should not unpack with wrong size (Path with more fields) 1`] = `"Wrong struct size for Node, expected 4 but was 3"`; +exports[`#unit BoltProtocolV5x0 .unpack() should not unpack with wrong size (Path with more fields) 1`] = `"Wrong struct size for Path, expected 3 but was 4"`; exports[`#unit BoltProtocolV5x0 .unpack() should not unpack with wrong size (Point with less fields) 1`] = `"Wrong struct size for Point2D, expected 3 but was 2"`; diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v1.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v1.test.js index 533f0023b..9d69a2909 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v1.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v1.test.js @@ -568,7 +568,8 @@ describe('#unit BoltProtocolV1', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -580,7 +581,7 @@ describe('#unit BoltProtocolV1', () => { ['Date', new structure.Structure(0x44, [1])], ['LocalDateTime', new structure.Structure(0x64, [1, 2])], ['DateTimeWithZoneOffset', new structure.Structure(0x46, [1, 2, 3])], - ['DateTimeWithZoneId', new structure.Structure(0x66, [1, 2, 'America/Sao Paulo'])] + ['DateTimeWithZoneId', new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo'])] ])('should unpack future structs as structs (%s)', (_, struct) => { const buffer = alloc(256) const protocol = new BoltProtocolV1( diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v2.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v2.test.js index 94575ea0a..a9d1f1a50 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v2.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v2.test.js @@ -154,7 +154,7 @@ describe('#unit BoltProtocolV2', () => { ['Time', new Time(1, 1, 1, 1, 1)], ['Date', new Date(1, 1, 1)], ['LocalDateTime', new LocalDateTime(1, 1, 1, 1, 1, 1, 1)], - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)], ['Point2D', new Point(1, 1, 1)], ['Point3D', new Point(1, 1, 1, 1)] @@ -380,7 +380,7 @@ describe('#unit BoltProtocolV2', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const buffer = alloc(256) @@ -396,7 +396,8 @@ describe('#unit BoltProtocolV2', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -442,8 +443,8 @@ describe('#unit BoltProtocolV2', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack spatial types and temporal types (%s)', (_, struct, object) => { const buffer = alloc(256) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v3.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v3.test.js index f8a6e914a..b3139c3cd 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v3.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v3.test.js @@ -359,7 +359,7 @@ describe('#unit BoltProtocolV3', () => { ['Time', new Time(1, 1, 1, 1, 1)], ['Date', new Date(1, 1, 1)], ['LocalDateTime', new LocalDateTime(1, 1, 1, 1, 1, 1, 1)], - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)], ['Point2D', new Point(1, 1, 1)], ['Point3D', new Point(1, 1, 1, 1)] @@ -585,7 +585,7 @@ describe('#unit BoltProtocolV3', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const buffer = alloc(256) @@ -601,7 +601,8 @@ describe('#unit BoltProtocolV3', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -647,8 +648,8 @@ describe('#unit BoltProtocolV3', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack spatial types and temporal types (%s)', (_, struct, object) => { const buffer = alloc(256) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v4x0.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v4x0.test.js index d92f36330..0bd626c9d 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v4x0.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v4x0.test.js @@ -277,7 +277,7 @@ describe('#unit BoltProtocolV4x0', () => { ['Time', new Time(1, 1, 1, 1, 1)], ['Date', new Date(1, 1, 1)], ['LocalDateTime', new LocalDateTime(1, 1, 1, 1, 1, 1, 1)], - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)], ['Point2D', new Point(1, 1, 1)], ['Point3D', new Point(1, 1, 1, 1)] @@ -503,7 +503,7 @@ describe('#unit BoltProtocolV4x0', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const buffer = alloc(256) @@ -519,7 +519,8 @@ describe('#unit BoltProtocolV4x0', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -565,8 +566,8 @@ describe('#unit BoltProtocolV4x0', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack spatial types and temporal types (%s)', (_, struct, object) => { const buffer = alloc(256) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v4x1.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v4x1.test.js index 48f8ca724..c80b94f86 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v4x1.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v4x1.test.js @@ -151,7 +151,7 @@ describe('#unit BoltProtocolV4x1', () => { ['Time', new Time(1, 1, 1, 1, 1)], ['Date', new Date(1, 1, 1)], ['LocalDateTime', new LocalDateTime(1, 1, 1, 1, 1, 1, 1)], - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)], ['Point2D', new Point(1, 1, 1)], ['Point3D', new Point(1, 1, 1, 1)] @@ -377,7 +377,7 @@ describe('#unit BoltProtocolV4x1', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const buffer = alloc(256) @@ -393,7 +393,8 @@ describe('#unit BoltProtocolV4x1', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -439,8 +440,8 @@ describe('#unit BoltProtocolV4x1', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack spatial types and temporal types (%s)', (_, struct, object) => { const buffer = alloc(256) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v4x2.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v4x2.test.js index 2000283a3..998ac3206 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v4x2.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v4x2.test.js @@ -150,7 +150,7 @@ describe('#unit BoltProtocolV4x2', () => { ['Time', new Time(1, 1, 1, 1, 1)], ['Date', new Date(1, 1, 1)], ['LocalDateTime', new LocalDateTime(1, 1, 1, 1, 1, 1, 1)], - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)], ['Point2D', new Point(1, 1, 1)], ['Point3D', new Point(1, 1, 1, 1)] @@ -376,7 +376,7 @@ describe('#unit BoltProtocolV4x2', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const buffer = alloc(256) @@ -392,7 +392,8 @@ describe('#unit BoltProtocolV4x2', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -438,8 +439,8 @@ describe('#unit BoltProtocolV4x2', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack spatial types and temporal types (%s)', (_, struct, object) => { const buffer = alloc(256) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js index 34bc28f27..6243e1b01 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js @@ -363,7 +363,7 @@ describe('#unit BoltProtocolV4x3', () => { ['Time', new Time(1, 1, 1, 1, 1)], ['Date', new Date(1, 1, 1)], ['LocalDateTime', new LocalDateTime(1, 1, 1, 1, 1, 1, 1)], - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)], ['Point2D', new Point(1, 1, 1)], ['Point3D', new Point(1, 1, 1, 1)] @@ -589,7 +589,7 @@ describe('#unit BoltProtocolV4x3', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const buffer = alloc(256) @@ -605,7 +605,8 @@ describe('#unit BoltProtocolV4x3', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -651,8 +652,8 @@ describe('#unit BoltProtocolV4x3', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack spatial types and temporal types (%s)', (_, struct, object) => { const buffer = alloc(256) @@ -848,7 +849,7 @@ describe('#unit BoltProtocolV4x3', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x69, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x69, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const packable = protocol.packable(struct) @@ -857,7 +858,8 @@ describe('#unit BoltProtocolV4x3', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -900,7 +902,7 @@ describe('#unit BoltProtocolV4x3', () => { ], [ 'DateTimeWithZoneId/0x66', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']) ] ])('should unpack deprecated temporal types as unknown structs (%s)', (_, struct) => { const packable = protocol.packable(struct) @@ -948,7 +950,7 @@ describe('#unit BoltProtocolV4x3', () => { ], [ 'DateTimeWithZoneId/0x69', - new structure.Structure(0x69, [1, 2, 'America/Sao Paulo']) + new structure.Structure(0x69, [1, 2, 'America/Sao_Paulo']) ] ])('should unpack utc temporal types as unknown structs (%s)', (_, struct) => { const packable = protocol.packable(struct) @@ -969,8 +971,8 @@ describe('#unit BoltProtocolV4x3', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack temporal types without utc fix (%s)', (_, struct, object) => { const packable = protocol.packable(struct) @@ -984,7 +986,7 @@ describe('#unit BoltProtocolV4x3', () => { }) it.each([ - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)] ])('should pack temporal types (no utc) (%s)', (_, object) => { const packable = protocol.packable(object) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js index a0a046ace..945ded5da 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js @@ -396,7 +396,7 @@ describe('#unit BoltProtocolV4x4', () => { ['Time', new Time(1, 1, 1, 1, 1)], ['Date', new Date(1, 1, 1)], ['LocalDateTime', new LocalDateTime(1, 1, 1, 1, 1, 1, 1)], - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)], ['Point2D', new Point(1, 1, 1)], ['Point3D', new Point(1, 1, 1, 1)] @@ -622,7 +622,7 @@ describe('#unit BoltProtocolV4x4', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const buffer = alloc(256) @@ -638,7 +638,8 @@ describe('#unit BoltProtocolV4x4', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -684,8 +685,8 @@ describe('#unit BoltProtocolV4x4', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack spatial types and temporal types (%s)', (_, struct, object) => { const buffer = alloc(256) @@ -881,7 +882,7 @@ describe('#unit BoltProtocolV4x4', () => { ], [ 'DateTimeWithZoneId with more fields', - new structure.Structure(0x69, [1, 2, 'America/Sao Paulo', 'Brasil']) + new structure.Structure(0x69, [1, 2, 'America/Sao_Paulo', 'Brasil']) ] ])('should not unpack with wrong size (%s)', (_, struct) => { const packable = protocol.packable(struct) @@ -890,7 +891,8 @@ describe('#unit BoltProtocolV4x4', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -933,7 +935,7 @@ describe('#unit BoltProtocolV4x4', () => { ], [ 'DateTimeWithZoneId/0x66', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']) ] ])('should unpack deprecated temporal types as unknown structs (%s)', (_, struct) => { const packable = protocol.packable(struct) @@ -981,7 +983,7 @@ describe('#unit BoltProtocolV4x4', () => { ], [ 'DateTimeWithZoneId/0x69', - new structure.Structure(0x69, [1, 2, 'America/Sao Paulo']) + new structure.Structure(0x69, [1, 2, 'America/Sao_Paulo']) ] ])('should unpack utc temporal types as unknown structs (%s)', (_, struct) => { const packable = protocol.packable(struct) @@ -1002,8 +1004,8 @@ describe('#unit BoltProtocolV4x4', () => { ], [ 'DateTimeWithZoneId', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']), - new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao Paulo') + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']), + new DateTime(1970, 1, 1, 0, 0, 1, 2, undefined, 'America/Sao_Paulo') ] ])('should unpack temporal types without utc fix (%s)', (_, struct, object) => { const packable = protocol.packable(struct) @@ -1017,7 +1019,7 @@ describe('#unit BoltProtocolV4x4', () => { }) it.each([ - ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao Paulo')], + ['DateTimeWithZoneId', new DateTime(1, 1, 1, 1, 1, 1, 1, undefined, 'America/Sao_Paulo')], ['DateTime', new DateTime(1, 1, 1, 1, 1, 1, 1, 1)] ])('should pack temporal types (no utc) (%s)', (_, object) => { const packable = protocol.packable(object) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js index 223cac107..a2bcd6c99 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js @@ -790,7 +790,8 @@ describe('#unit BoltProtocolV5x0', () => { buffer.reset() - expect(() => protocol.unpack(buffer)).toThrowErrorMatchingSnapshot() + const unpacked = protocol.unpack(buffer) + expect(() => unpacked instanceof structure.Structure).toThrowErrorMatchingSnapshot() }) it.each([ @@ -891,7 +892,7 @@ describe('#unit BoltProtocolV5x0', () => { ], [ 'DateTimeWithZoneId/0x66', - new structure.Structure(0x66, [1, 2, 'America/Sao Paulo']) + new structure.Structure(0x66, [1, 2, 'America/Sao_Paulo']) ] ])('should unpack deprecated temporal types as unknown structs (%s)', (_, struct) => { const buffer = alloc(256) diff --git a/packages/core/src/internal/temporal-util.ts b/packages/core/src/internal/temporal-util.ts index 7598d237e..f23e43884 100644 --- a/packages/core/src/internal/temporal-util.ts +++ b/packages/core/src/internal/temporal-util.ts @@ -417,6 +417,16 @@ export function assertValidNanosecond ( ) } +export function assertValidZoneId (fieldName: string, zoneId: string): void { + try { + Intl.DateTimeFormat(undefined, { timeZone: zoneId }) + } catch (e) { + throw newError( + `${fieldName} is expected to be a valid ZoneId but was: "${zoneId}"` + ) + } +} + /** * Check if the given value is of expected type and is in the expected range. * @param {Integer|number} value the value to check. diff --git a/packages/core/src/internal/util.ts b/packages/core/src/internal/util.ts index f5d6bbbbf..2b6b3e722 100644 --- a/packages/core/src/internal/util.ts +++ b/packages/core/src/internal/util.ts @@ -224,6 +224,35 @@ function isString (str: any): str is string { return Object.prototype.toString.call(str) === '[object String]' } +/** + * Creates a object which all method call will throw the given error + * + * @param {Error} error The error + * @param {any} object The object. Default: {} + * @returns {any} A broken object + */ +function createBrokenObject (error: Error, object: any = {}): T { + const fail: () => T = () => { + throw error + } + + return new Proxy(object, { + get: fail, + set: fail, + apply: fail, + construct: fail, + defineProperty: fail, + deleteProperty: fail, + getOwnPropertyDescriptor: fail, + getPrototypeOf: fail, + has: fail, + isExtensible: fail, + ownKeys: fail, + preventExtensions: fail, + setPrototypeOf: fail + }) +} + export { isEmptyObjectOrNull, isObject, @@ -235,5 +264,6 @@ export { assertValidDate, validateQueryAndParameters, ENCRYPTION_ON, - ENCRYPTION_OFF + ENCRYPTION_OFF, + createBrokenObject } diff --git a/packages/core/src/temporal-types.ts b/packages/core/src/temporal-types.ts index 26cc0179e..36281048e 100644 --- a/packages/core/src/temporal-types.ts +++ b/packages/core/src/temporal-types.ts @@ -768,6 +768,7 @@ function verifyTimeZoneArguments ( if (idDefined) { assertString(timeZoneId, 'Time zone ID') + util.assertValidZoneId('Time zone ID', timeZoneId) result[1] = timeZoneId } diff --git a/packages/neo4j-driver/test/temporal-types.test.js b/packages/neo4j-driver/test/temporal-types.test.js index 395ce09a6..b23a45066 100644 --- a/packages/neo4j-driver/test/temporal-types.test.js +++ b/packages/neo4j-driver/test/temporal-types.test.js @@ -43,8 +43,8 @@ const MIN_YEAR = -MAX_YEAR const MAX_TIME_ZONE_OFFSET = 64800 const MIN_TIME_ZONE_OFFSET = -MAX_TIME_ZONE_OFFSET const SECONDS_PER_MINUTE = 60 -const MIN_ZONE_ID = 'Etc/GMT+12' -const MAX_ZONE_ID = 'Etc/GMT-14' +const MIN_ZONE_ID = 'Pacific/Samoa' +const MAX_ZONE_ID = 'Pacific/Kiritimati' const ZONE_IDS = ['Europe/Zaporozhye', 'Europe/London', 'UTC', 'Africa/Cairo'] describe('#integration temporal-types', () => { @@ -643,9 +643,6 @@ describe('#integration temporal-types', () => { 'Asia/Yangon' ).toString() ).toEqual('-30455-05-05T12:24:10.000000123[Asia/Yangon]') - expect( - dateTimeWithZoneId(248, 12, 30, 23, 59, 59, 3, 'CET').toString() - ).toEqual('0248-12-30T23:59:59.000000003[CET]') }, 60000) it('should expose local time components in time', () => { @@ -1400,6 +1397,12 @@ describe('#integration temporal-types', () => { verifyTimeZoneOffset(neo4jDateTime5, -1 * 150 * 60, '-02:30') }, 60000) + it('should not create DateTime with invalid ZoneId', () => { + expect(() => dateTimeWithZoneId(1999, 10, 1, 10, 15, 0, 0, 'Europe/Neo4j')).toThrowError( + 'Time zone ID is expected to be a valid ZoneId but was: "Europe/Neo4j"' + ) + }) + function testSendAndReceiveRandomTemporalValues (valueGenerator) { const asyncFunction = (index, callback) => { testSendReceiveTemporalValue(valueGenerator()) diff --git a/packages/testkit-backend/src/request-handlers.js b/packages/testkit-backend/src/request-handlers.js index aecdfdace..9abc93dd8 100644 --- a/packages/testkit-backend/src/request-handlers.js +++ b/packages/testkit-backend/src/request-handlers.js @@ -342,11 +342,29 @@ export function StartTest (context, { testName }, wire) { } const shouldRunTest = context.getShouldRunTestFunction() shouldRunTest(testName, { - onRun: () => wire.writeResponse(responses.RunTest()), + onRun: () => { + if (testName === 'neo4j.datatypes.test_temporal_types.TestDataTypes.test_date_time_cypher_created_tz_id') { + return wire.writeResponse(responses.RunSubTests()) + } + return wire.writeResponse(responses.RunTest()) + }, onSkip: reason => wire.writeResponse(responses.SkipTest({ reason })) }) } +export function StartSubTest (context, { testName, subtestArguments }, wire) { + if (testName === 'neo4j.datatypes.test_temporal_types.TestDataTypes.test_date_time_cypher_created_tz_id') { + try { + Intl.DateTimeFormat(undefined, { timeZone: subtestArguments.tz_id }) + return wire.writeResponse(responses.RunTest()) + } catch (e) { + wire.writeResponse(responses.SkipTest({ reason: `Unsupported tzid: ${subtestArguments.tz_id}` })) + } + } else { + wire.writeBackendError(`No entry for ${testName} in StartSubTest`) + } +} + export function GetFeatures (context, _params, wire) { wire.writeResponse(responses.FeatureList({ features: context.getFeatures() diff --git a/packages/testkit-backend/src/responses.js b/packages/testkit-backend/src/responses.js index c0331bc70..03a9f0487 100644 --- a/packages/testkit-backend/src/responses.js +++ b/packages/testkit-backend/src/responses.js @@ -85,6 +85,10 @@ export function RunTest () { return response('RunTest', null) } +export function RunSubTests () { + return response('RunSubTests', null) +} + export function SkipTest ({ reason }) { return response('SkipTest', { reason }) } diff --git a/packages/testkit-backend/src/skipped-tests/common.js b/packages/testkit-backend/src/skipped-tests/common.js index e0602f137..bbe75f9be 100644 --- a/packages/testkit-backend/src/skipped-tests/common.js +++ b/packages/testkit-backend/src/skipped-tests/common.js @@ -1,8 +1,11 @@ -import skip, { ifEquals, ifEndsWith } from './skip' +import skip, { ifEquals, ifEndsWith, endsWith, ifStartsWith, startsWith, not } from './skip' const skippedTests = [ skip( 'Driver does not return offset for old DateTime implementations', + ifStartsWith('stub.types.test_temporal_types.TestTemporalTypes') + .and(not(startsWith('stub.types.test_temporal_types.TestTemporalTypesV5'))) + .and(endsWith('test_zoned_date_time')), ifEquals('neo4j.datatypes.test_temporal_types.TestDataTypes.test_nested_datetime'), ifEquals('neo4j.datatypes.test_temporal_types.TestDataTypes.test_should_echo_all_timezone_ids'), ifEquals('neo4j.datatypes.test_temporal_types.TestDataTypes.test_cypher_created_datetime') diff --git a/packages/testkit-backend/src/skipped-tests/skip.js b/packages/testkit-backend/src/skipped-tests/skip.js index adb997a97..30d5d14b8 100644 --- a/packages/testkit-backend/src/skipped-tests/skip.js +++ b/packages/testkit-backend/src/skipped-tests/skip.js @@ -1,21 +1,42 @@ + +function asComposablePredicate (predicate) { + return new Proxy(predicate, { + get: (target, p) => { + if (p === 'and') { + return otherPredicate => asComposablePredicate(testName => target(testName) && otherPredicate(testName)) + } else if (p === 'or') { + return otherPredicate => asComposablePredicate(testName => target(testName) || otherPredicate(testName)) + } + return target[p] + } + }) +} + export function ifEndsWith (suffix) { - return testName => testName.endsWith(suffix) + return asComposablePredicate(testName => testName.endsWith(suffix)) } export function ifStartsWith (prefix) { - return testName => testName.startsWith(prefix) + return asComposablePredicate(testName => testName.startsWith(prefix)) } export function ifEquals (expectedName) { - return testName => testName === expectedName + return asComposablePredicate(testName => testName === expectedName) } export function or () { - return testName => [...arguments].find(predicate => predicate(testName)) + return asComposablePredicate(testName => [...arguments].find(predicate => predicate(testName))) +} + +export function not (predicate) { + return asComposablePredicate(testName => !predicate(testName)) } export function skip (reason, ...predicate) { return { reason, predicate: or(...predicate) } } +export const endsWith = ifEndsWith +export const startsWith = ifStartsWith + export default skip