diff --git a/src/interfaces.ts b/src/interfaces.ts index f1eb54e..d4a6b74 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -94,7 +94,7 @@ export interface XMLBuilderOptions { * - offset - the offset of the invalid character * - str - the input string */ - invalidCharReplacement: string | ((char: string, offset:number, str: string) => string) | undefined + invalidCharReplacement: string | ((char: string, offset: number, str: string) => string) | undefined } /** @@ -309,6 +309,11 @@ export type MapWriterOptions = BaseWriterOptions & { * `false`. */ group?: boolean + /** + * Outputs child nodes as an array, even if the parent node has zero or one + * child nodes. + */ + verbose?: boolean } /** @@ -322,6 +327,11 @@ export type ObjectWriterOptions = BaseWriterOptions & { * `false`. */ group?: boolean + /** + * Outputs child nodes as an array, even if the parent node has zero or one + * child nodes. + */ + verbose?: boolean } /** @@ -426,6 +436,11 @@ export type JSONWriterOptions = BaseWriterOptions & { * `false`. */ group?: boolean + /** + * Outputs child nodes as an array, even if the parent node has zero or one + * child nodes. + */ + verbose?: boolean } /** @@ -859,11 +874,11 @@ export interface XMLBuilder { */ toObject(writerOptions?: ObjectWriterOptions): XMLSerializedAsObject | XMLSerializedAsObjectArray - /** - * Converts the node into its object representation using ES6 maps. - * - * @param options - serialization options - */ + /** + * Converts the node into its object representation using ES6 maps. + * + * @param options - serialization options + */ toObject(writerOptions: MapWriterOptions): XMLSerializedAsMap | XMLSerializedAsMapArray /** @@ -1143,13 +1158,13 @@ export type XMLBuilderCBOptions = CBWriterOptions & { * Defines namespace aliases. */ namespaceAlias: { [key: string]: string | null } - /** - * Replacement for invalid characters in input strings. - * If `invalidCharReplacement` is a string, each invalid character in an input - * string will be replaced with it; otherwise if `invalidCharReplacement` - * is a function it will be passed each invalid character and should return - * a replacement character. - */ + /** + * Replacement for invalid characters in input strings. + * If `invalidCharReplacement` is a string, each invalid character in an input + * string will be replaced with it; otherwise if `invalidCharReplacement` + * is a function it will be passed each invalid character and should return + * a replacement character. + */ invalidCharReplacement: string | ((substring: string, ...args: any[]) => string) | undefined } @@ -1162,7 +1177,7 @@ export type BaseCBWriterOptions = { * - `"xml"` - Serializes the document as a string in XML format. * - `"json"` - Serializes the document as a JSON string. */ - format?: "xml" | "json" + format?: "xml" | "json" /** * Ensures that the document adheres to the syntax rules specified by the * XML specification. If this flag is set and the document is not well-formed @@ -1178,7 +1193,7 @@ export type BaseCBWriterOptions = { /** * Defines the options passed to the callback builder's XML writer. */ -export type XMLCBWriterOptions = BaseCBWriterOptions & { +export type XMLCBWriterOptions = BaseCBWriterOptions & { /** @inheritdoc */ format?: "xml" /** @@ -1231,7 +1246,7 @@ export type XMLCBWriterOptions = BaseCBWriterOptions & { /** * Defines the options passed to the callback builder's JSON writer. */ -export type JSONCBWriterOptions = BaseCBWriterOptions & { +export type JSONCBWriterOptions = BaseCBWriterOptions & { /** @inheritdoc */ format?: "json" /** diff --git a/src/writers/MapWriter.ts b/src/writers/MapWriter.ts index 094e75b..221f3bf 100644 --- a/src/writers/MapWriter.ts +++ b/src/writers/MapWriter.ts @@ -23,14 +23,16 @@ export class MapWriter extends BaseWriter this._currentList = [] @@ -174,7 +175,11 @@ export class ObjectWriter extends BaseWriter { + // https://github.com/oozcitak/xmlbuilder2/issues/30 + test("#30 - Conversion from XML to JSON array inconsistency", () => { + const input2 = $$.t` + + + X + 123 + + + Y + 321 + + ` + + const obj2 = $$.convert(input2, { format: 'object', verbose: true }) + expect(obj2).toEqual( + { + "data": [ + { + "row": [ + { + "@id": "0", + "TYPE": [ "X" ], + "ID": [ "123" ] + }, + { + "@id": "1", + "TYPE": [ "Y" ], + "ID": [ "321" ] + } + ] + } + ] + }) + expect($$.create(obj2).end({ headless: true, prettyPrint: true })).toBe(input2) + + const input1 = $$.t` + + + X + 123 + + ` + const obj1 = $$.convert(input1, { format: 'object', verbose: true }) + expect(obj1).toEqual( + { + "data": [ + { + "row": [ + { + "@id": "0", + "TYPE": [ "X" ], + "ID": [ "123" ] + } + ] + } + ] + }) + expect($$.create(obj1).end({ headless: true, prettyPrint: true })).toBe(input1) + }) + +}) diff --git a/test/writers/JSONWriter.test.ts b/test/writers/JSONWriter.test.ts index 65f0a8b..0ee4b32 100644 --- a/test/writers/JSONWriter.test.ts +++ b/test/writers/JSONWriter.test.ts @@ -196,4 +196,76 @@ describe('JSONWriter', () => { expect(() => ele.end({ format: "json" })).toThrow() }) + test("verbose", () => { + const input2 = $$.t` + + + X + 123 + + + Y + 321 + + ` + + const json2 = $$.convert(input2, { format: 'json', verbose: true, prettyPrint: true }) + expect(json2).toBe($$.t` + { + "data": [ + { + "row": [ + { + "@id": "0", + "TYPE": [ + "X" + ], + "ID": [ + "123" + ] + }, + { + "@id": "1", + "TYPE": [ + "Y" + ], + "ID": [ + "321" + ] + } + ] + } + ] + }`) + expect($$.create(json2).end({ headless: true, prettyPrint: true })).toBe(input2) + + const input1 = $$.t` + + + X + 123 + + ` + const json1 = $$.convert(input1, { format: 'json', verbose: true, prettyPrint: true }) + expect(json1).toEqual($$.t` + { + "data": [ + { + "row": [ + { + "@id": "0", + "TYPE": [ + "X" + ], + "ID": [ + "123" + ] + } + ] + } + ] + }`) + expect($$.create(json1).end({ headless: true, prettyPrint: true })).toBe(input1) + }) + }) diff --git a/test/writers/MapWriter.test.ts b/test/writers/MapWriter.test.ts index 5db1e1e..3c78dd6 100644 --- a/test/writers/MapWriter.test.ts +++ b/test/writers/MapWriter.test.ts @@ -169,4 +169,64 @@ describe('MapWriter', () => { expect(() => ele.end({ format: "map" })).toThrow() }) + test("verbose", () => { + const input2 = $$.t` + + + X + 123 + + + Y + 321 + + ` + + const result2 = $$.convert(input2, { format: 'map', verbose: true }) + expect($$.printMap(result2)).toBe($$.t` + M{ + data: [ + M{ + row: [ + M{ + @id: 0, + TYPE: [ X ], + ID: [ 123 ] + }, + M{ + @id: 1, + TYPE: [ Y ], + ID: [ 321 ] + } + ] + } + ] + }`) + expect($$.create(result2).end({ headless: true, prettyPrint: true })).toBe(input2) + + const input1 = $$.t` + + + X + 123 + + ` + const result1 = $$.convert(input1, { format: 'map', verbose: true }) + expect($$.printMap(result1)).toEqual($$.t` + M{ + data: [ + M{ + row: [ + M{ + @id: 0, + TYPE: [ X ], + ID: [ 123 ] + } + ] + } + ] + }`) + expect($$.create(result1).end({ headless: true, prettyPrint: true })).toBe(input1) + }) + }) diff --git a/test/writers/ObjectWriter.test.ts b/test/writers/ObjectWriter.test.ts index cc1e041..5898465 100644 --- a/test/writers/ObjectWriter.test.ts +++ b/test/writers/ObjectWriter.test.ts @@ -660,4 +660,64 @@ describe('ObjectWriter', () => { expect(result).toEqual({ foo: { }, bar: { } }) }) + test("verbose", () => { + const input2 = $$.t` + + + X + 123 + + + Y + 321 + + ` + + const obj2 = $$.convert(input2, { format: 'object', verbose: true }) + expect(obj2).toEqual( + { + "data": [ + { + "row": [ + { + "@id": "0", + "TYPE": [ "X" ], + "ID": [ "123" ] + }, + { + "@id": "1", + "TYPE": [ "Y" ], + "ID": [ "321" ] + } + ] + } + ] + }) + expect($$.create(obj2).end({ headless: true, prettyPrint: true })).toBe(input2) + + const input1 = $$.t` + + + X + 123 + + ` + const obj1 = $$.convert(input1, { format: 'object', verbose: true }) + expect(obj1).toEqual( + { + "data": [ + { + "row": [ + { + "@id": "0", + "TYPE": [ "X" ], + "ID": [ "123" ] + } + ] + } + ] + }) + expect($$.create(obj1).end({ headless: true, prettyPrint: true })).toBe(input1) + }) + })