@featurevisor/core 2.22.1 → 2.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/coverage/clover.xml +164 -274
  3. package/coverage/coverage-final.json +3 -6
  4. package/coverage/lcov-report/builder/allocator.ts.html +1 -1
  5. package/coverage/lcov-report/builder/buildDatafile.ts.html +8 -2
  6. package/coverage/lcov-report/builder/buildScopedConditions.ts.html +1 -1
  7. package/coverage/lcov-report/builder/buildScopedDatafile.ts.html +1 -1
  8. package/coverage/lcov-report/builder/buildScopedSegments.ts.html +1 -1
  9. package/coverage/lcov-report/builder/convertToV1.ts.html +1 -1
  10. package/coverage/lcov-report/builder/getFeatureRanges.ts.html +1 -1
  11. package/coverage/lcov-report/builder/hashes.ts.html +1 -1
  12. package/coverage/lcov-report/builder/index.html +1 -1
  13. package/coverage/lcov-report/builder/mutateVariables.ts.html +1 -1
  14. package/coverage/lcov-report/builder/mutator.ts.html +1 -1
  15. package/coverage/lcov-report/builder/revision.ts.html +1 -1
  16. package/coverage/lcov-report/builder/traffic.ts.html +1 -1
  17. package/coverage/lcov-report/config/index.html +1 -1
  18. package/coverage/lcov-report/config/index.ts.html +1 -1
  19. package/coverage/lcov-report/config/projectConfig.ts.html +3 -3
  20. package/coverage/lcov-report/datasource/adapter.ts.html +1 -1
  21. package/coverage/lcov-report/datasource/datasource.ts.html +2 -2
  22. package/coverage/lcov-report/datasource/filesystemAdapter.ts.html +3 -3
  23. package/coverage/lcov-report/datasource/index.html +1 -1
  24. package/coverage/lcov-report/datasource/index.ts.html +1 -1
  25. package/coverage/lcov-report/generate-code/index.html +1 -1
  26. package/coverage/lcov-report/generate-code/typescript.ts.html +1 -1
  27. package/coverage/lcov-report/index.html +9 -24
  28. package/coverage/lcov-report/linter/attributeSchema.ts.html +1 -1
  29. package/coverage/lcov-report/linter/checkCircularDependency.ts.html +1 -1
  30. package/coverage/lcov-report/linter/checkPercentageExceedingSlot.ts.html +1 -1
  31. package/coverage/lcov-report/linter/conditionSchema.ts.html +1 -1
  32. package/coverage/lcov-report/linter/featureSchema.ts.html +1 -1
  33. package/coverage/lcov-report/linter/groupSchema.ts.html +1 -1
  34. package/coverage/lcov-report/linter/index.html +1 -1
  35. package/coverage/lcov-report/linter/lintProject.ts.html +1 -1
  36. package/coverage/lcov-report/linter/mutationNotation.ts.html +1 -1
  37. package/coverage/lcov-report/linter/printError.ts.html +1 -1
  38. package/coverage/lcov-report/linter/schema.ts.html +1 -1
  39. package/coverage/lcov-report/linter/segmentSchema.ts.html +1 -1
  40. package/coverage/lcov-report/linter/testSchema.ts.html +1 -1
  41. package/coverage/lcov-report/list/index.html +1 -1
  42. package/coverage/lcov-report/list/matrix.ts.html +1 -1
  43. package/coverage/lcov-report/tester/cliFormat.ts.html +1 -1
  44. package/coverage/lcov-report/tester/helpers.ts.html +1 -1
  45. package/coverage/lcov-report/tester/index.html +1 -1
  46. package/coverage/lcov-report/utils/extractKeys.ts.html +1 -1
  47. package/coverage/lcov-report/utils/git.ts.html +2 -2
  48. package/coverage/lcov-report/utils/index.html +1 -1
  49. package/coverage/lcov-report/utils/index.ts.html +1 -1
  50. package/coverage/lcov-report/utils/pretty.ts.html +1 -1
  51. package/coverage/lcov.info +281 -491
  52. package/lib/builder/buildDatafile.d.ts +1 -0
  53. package/lib/builder/buildDatafile.js +1 -0
  54. package/lib/builder/buildDatafile.js.map +1 -1
  55. package/lib/builder/buildDatafile.spec.js +1 -1
  56. package/lib/builder/buildDatafile.spec.js.map +1 -1
  57. package/lib/builder/buildProject.js +13 -0
  58. package/lib/builder/buildProject.js.map +1 -1
  59. package/lib/config/projectConfig.d.ts +1 -1
  60. package/lib/config/projectConfig.js +1 -1
  61. package/lib/config/projectConfig.js.map +1 -1
  62. package/lib/datasource/filesystemAdapter.js.map +1 -1
  63. package/lib/index.d.ts +1 -1
  64. package/lib/index.js +1 -1
  65. package/lib/index.js.map +1 -1
  66. package/lib/linter/featureSchema.d.ts +8 -8
  67. package/package.json +5 -6
  68. package/src/builder/buildDatafile.spec.ts +1 -1
  69. package/src/builder/buildDatafile.ts +2 -0
  70. package/src/builder/buildProject.ts +14 -0
  71. package/src/config/projectConfig.ts +1 -1
  72. package/src/datasource/datasource.ts +1 -1
  73. package/src/datasource/filesystemAdapter.ts +1 -1
  74. package/src/index.ts +2 -1
  75. package/src/utils/git.ts +1 -1
  76. package/coverage/lcov-report/parsers/index.html +0 -146
  77. package/coverage/lcov-report/parsers/index.ts.html +0 -151
  78. package/coverage/lcov-report/parsers/json.ts.html +0 -118
  79. package/coverage/lcov-report/parsers/yml.ts.html +0 -589
  80. package/lib/parsers/index.d.ts +0 -15
  81. package/lib/parsers/index.js +0 -15
  82. package/lib/parsers/index.js.map +0 -1
  83. package/lib/parsers/json.d.ts +0 -2
  84. package/lib/parsers/json.js +0 -13
  85. package/lib/parsers/json.js.map +0 -1
  86. package/lib/parsers/json.spec.d.ts +0 -1
  87. package/lib/parsers/json.spec.js +0 -35
  88. package/lib/parsers/json.spec.js.map +0 -1
  89. package/lib/parsers/yml.d.ts +0 -2
  90. package/lib/parsers/yml.js +0 -154
  91. package/lib/parsers/yml.js.map +0 -1
  92. package/lib/parsers/yml.spec.d.ts +0 -1
  93. package/lib/parsers/yml.spec.js +0 -143
  94. package/lib/parsers/yml.spec.js.map +0 -1
  95. package/src/parsers/index.ts +0 -22
  96. package/src/parsers/json.spec.ts +0 -36
  97. package/src/parsers/json.ts +0 -11
  98. package/src/parsers/yml.spec.ts +0 -174
  99. package/src/parsers/yml.ts +0 -168
@@ -1 +0,0 @@
1
- export {};
@@ -1,35 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const json_1 = require("./json");
4
- describe("core :: parser :: jsonParser", () => {
5
- it("should parse JSON string into object", () => {
6
- const jsonString = '{"foo":1,"bar":"baz","arr":[1,2]}';
7
- const result = json_1.jsonParser.parse(jsonString);
8
- expect(result).toEqual({ foo: 1, bar: "baz", arr: [1, 2] });
9
- });
10
- it("should stringify object into JSON string (pretty-printed)", () => {
11
- const obj = { foo: 1, bar: "baz", arr: [1, 2] };
12
- const jsonString = json_1.jsonParser.stringify(obj);
13
- const expectedString = `{
14
- "foo": 1,
15
- "bar": "baz",
16
- "arr": [
17
- 1,
18
- 2
19
- ]
20
- }`;
21
- expect(jsonString).toBe(expectedString);
22
- });
23
- it("should parse and then stringify to preserve content", () => {
24
- const original = { alpha: "a", num: 42, bool: true, nullish: null, nested: { z: "x" } };
25
- const str = json_1.jsonParser.stringify(original);
26
- const reparsed = json_1.jsonParser.parse(str);
27
- expect(reparsed).toEqual(original);
28
- });
29
- it("should throw if invalid JSON string is provided to parse", () => {
30
- expect(() => {
31
- json_1.jsonParser.parse("this is not json");
32
- }).toThrow();
33
- });
34
- });
35
- //# sourceMappingURL=json.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"json.spec.js","sourceRoot":"","sources":["../../src/parsers/json.spec.ts"],"names":[],"mappings":";;AAAA,iCAAoC;AAEpC,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,UAAU,GAAG,mCAAmC,CAAC;QACvD,MAAM,MAAM,GAAG,iBAAU,CAAC,KAAK,CAA8C,UAAU,CAAC,CAAC;QACzF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,iBAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,cAAc,GAAG;;;;;;;EAOzB,CAAC;QACC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;QACxF,MAAM,GAAG,GAAG,iBAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,iBAAU,CAAC,KAAK,CAAkB,GAAG,CAAC,CAAC;QACxD,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,GAAG,EAAE;YACV,iBAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- import type { CustomParser } from "./index";
2
- export declare const ymlParser: CustomParser;
@@ -1,154 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ymlParser = void 0;
4
- const fs = require("fs");
5
- const yaml_1 = require("yaml");
6
- const types_1 = require("yaml/types");
7
- function getKeyString(keyNode) {
8
- if (keyNode == null)
9
- return undefined;
10
- if (typeof keyNode.value !== "undefined") {
11
- return String(keyNode.value);
12
- }
13
- return typeof keyNode === "string" ? keyNode : undefined;
14
- }
15
- function copyComments(source, target) {
16
- if (source.comment != null)
17
- target.comment = source.comment;
18
- if (source.commentBefore != null)
19
- target.commentBefore = source.commentBefore;
20
- const srcVal = source.value;
21
- const tgtVal = target.value;
22
- if (srcVal && tgtVal && typeof tgtVal === "object" && tgtVal !== null) {
23
- const t = tgtVal;
24
- if (srcVal.comment != null)
25
- t.comment = srcVal.comment;
26
- if (srcVal.commentBefore != null)
27
- t.commentBefore = srcVal.commentBefore;
28
- }
29
- }
30
- function isYamlMap(node) {
31
- return node != null && typeof node === "object" && Array.isArray(node.items);
32
- }
33
- function isYamlSeq(node) {
34
- return node != null && typeof node === "object" && Array.isArray(node.items);
35
- }
36
- function seqItemValueKey(item) {
37
- if (item == null)
38
- return String(item);
39
- const n = item;
40
- if (typeof n.value !== "undefined")
41
- return JSON.stringify(n.value);
42
- if (typeof n.toJSON === "function")
43
- return JSON.stringify(n.toJSON());
44
- return JSON.stringify(item);
45
- }
46
- function primitiveValueKey(v) {
47
- return JSON.stringify(v);
48
- }
49
- function createValueWithComments(schema, oldNode, newValue) {
50
- if (newValue === null || typeof newValue !== "object") {
51
- const node = new types_1.Scalar(newValue);
52
- const old = oldNode;
53
- if (old) {
54
- if (old.comment != null)
55
- node.comment = old.comment;
56
- if (old.commentBefore != null)
57
- node.commentBefore = old.commentBefore;
58
- }
59
- return node;
60
- }
61
- if (Array.isArray(newValue)) {
62
- const oldSeq = isYamlSeq(oldNode) ? oldNode : null;
63
- const oldItemsByValue = new Map();
64
- if (oldSeq && oldSeq.items) {
65
- for (const item of oldSeq.items) {
66
- oldItemsByValue.set(seqItemValueKey(item), item);
67
- }
68
- }
69
- const newSeq = schema.createNode([]);
70
- for (const el of newValue) {
71
- const oldItem = oldItemsByValue.get(primitiveValueKey(el));
72
- const itemNode = createValueWithComments(schema, oldItem, el);
73
- newSeq.add(itemNode);
74
- }
75
- return newSeq;
76
- }
77
- // newValue is a plain object; preserve comments from old map if present
78
- const oldMap = isYamlMap(oldNode) ? oldNode : null;
79
- const oldPairsByKey = new Map();
80
- if (oldMap) {
81
- for (const pair of (oldMap.items || [])) {
82
- const keyStr = getKeyString(pair.key);
83
- if (keyStr !== undefined)
84
- oldPairsByKey.set(keyStr, pair);
85
- }
86
- }
87
- const newMap = schema.createNode({});
88
- const obj = newValue;
89
- for (const k of Object.keys(obj)) {
90
- const oldPair = oldPairsByKey.get(k);
91
- const childOldNode = oldPair ? oldPair.value : undefined;
92
- const childNewValue = createValueWithComments(schema, childOldNode, obj[k]);
93
- const newPair = schema.createPair(k, childNewValue);
94
- if (oldPair)
95
- copyComments(oldPair, newPair);
96
- newMap.add(newPair);
97
- }
98
- const result = newMap;
99
- const oldVal = oldNode;
100
- if (oldVal && result) {
101
- if (oldVal.comment != null)
102
- result.comment = oldVal.comment;
103
- if (oldVal.commentBefore != null)
104
- result.commentBefore = oldVal.commentBefore;
105
- }
106
- return result;
107
- }
108
- function replaceContentsPreservingComments(doc, newContent) {
109
- const oldRoot = doc.contents;
110
- if (!oldRoot || !Array.isArray(oldRoot.items)) {
111
- doc.contents = doc.schema.createNode(newContent);
112
- return;
113
- }
114
- const schema = doc.schema;
115
- const oldPairsByKey = new Map();
116
- for (const pair of oldRoot.items) {
117
- const keyStr = getKeyString(pair.key);
118
- if (keyStr !== undefined)
119
- oldPairsByKey.set(keyStr, pair);
120
- }
121
- const newMap = schema.createNode({});
122
- for (const key of Object.keys(newContent)) {
123
- const oldPair = oldPairsByKey.get(key);
124
- const valueNode = createValueWithComments(schema, oldPair?.value, newContent[key]);
125
- const newPair = schema.createPair(key, valueNode);
126
- if (oldPair)
127
- copyComments(oldPair, newPair);
128
- newMap.add(newPair);
129
- }
130
- doc.contents = newMap;
131
- }
132
- exports.ymlParser = {
133
- extension: "yml",
134
- parse: function (content) {
135
- return (0, yaml_1.parse)(content);
136
- },
137
- stringify: function (content, filePath) {
138
- if (!filePath || !fs.existsSync(filePath)) {
139
- return (0, yaml_1.stringify)(content);
140
- }
141
- const fileContent = fs.readFileSync(filePath, "utf8");
142
- if (!fileContent.trim()) {
143
- return (0, yaml_1.stringify)(content);
144
- }
145
- // newObject is the final saved object; existing file is only for ordering/comments
146
- if (content === null || typeof content !== "object" || Array.isArray(content)) {
147
- throw new Error("Cannot set root document to a primitive value");
148
- }
149
- const doc = (0, yaml_1.parseDocument)(fileContent);
150
- replaceContentsPreservingComments(doc, content);
151
- return doc.toString();
152
- },
153
- };
154
- //# sourceMappingURL=yml.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"yml.js","sourceRoot":"","sources":["../../src/parsers/yml.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,143 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const yml_1 = require("./yml");
4
- describe("core :: parser :: ymlParser", () => {
5
- it("should parse YAML string into object", () => {
6
- const yamlString = `
7
- foo: 1
8
- bar: baz
9
- arr:
10
- - 1
11
- - 2
12
- `;
13
- const result = yml_1.ymlParser.parse(yamlString);
14
- expect(result).toEqual({ foo: 1, bar: "baz", arr: [1, 2] });
15
- });
16
- it("should stringify object into YAML string", () => {
17
- const obj = { foo: 1, bar: "baz", arr: [1, 2] };
18
- const yamlString = yml_1.ymlParser.stringify(obj);
19
- expect(yamlString.trim()).toBe(`foo: 1
20
- bar: baz
21
- arr:
22
- - 1
23
- - 2`);
24
- });
25
- it("should parse and then stringify to preserve YAML content semantically", () => {
26
- const original = {
27
- alpha: "a",
28
- num: 42,
29
- bool: true,
30
- nullish: null,
31
- nested: { z: "x", y: [1, 2] },
32
- };
33
- const str = yml_1.ymlParser.stringify(original);
34
- const reparsed = yml_1.ymlParser.parse(str);
35
- expect(reparsed).toEqual(original);
36
- });
37
- it("should throw if invalid YAML string is provided to parse", () => {
38
- expect(() => {
39
- yml_1.ymlParser.parse("foo: : bar");
40
- }).toThrow();
41
- });
42
- describe("stringify() with filePath argument (existing file for ordering/comments only)", () => {
43
- const fs = require("fs");
44
- const path = require("path");
45
- const os = require("os");
46
- let tempFile;
47
- beforeEach(() => {
48
- tempFile = path.join(os.tmpdir(), `test_${Math.random()}.yml`);
49
- });
50
- afterEach(() => {
51
- if (fs.existsSync(tempFile)) {
52
- fs.unlinkSync(tempFile);
53
- }
54
- });
55
- it("should save exactly the new object; existing file is only for ordering/comments", () => {
56
- const beforeYaml = `
57
- foo: 1 # foo comment here
58
- extra: blah
59
-
60
- ##
61
- # Comment above nested
62
- #
63
- nested:
64
- a: x
65
- b: y # b comment
66
- array:
67
- - one # one
68
- - two # two
69
- - three # three
70
- `.trim() + "\n";
71
- const newContent = {
72
- foo: 42,
73
- bar: "new",
74
- nested: { b: "updated", c: "added" },
75
- array: ["two", "three", "four"],
76
- };
77
- const afterYaml = `
78
- foo: 42 # foo comment here
79
- bar: new
80
- ##
81
- # Comment above nested
82
- #
83
- nested:
84
- b: updated # b comment
85
- c: added
86
- array:
87
- - two # two
88
- - three # three
89
- - four
90
- `.trim() + "\n";
91
- fs.writeFileSync(tempFile, beforeYaml);
92
- const output = yml_1.ymlParser.stringify(newContent, tempFile);
93
- expect(output).toBe(afterYaml);
94
- });
95
- it("should replace the root if YAML file is empty", () => {
96
- const beforeYaml = "";
97
- const afterYaml = `
98
- hello: world
99
- test:
100
- - 1
101
- - 2
102
- - 3
103
- `.trim() + "\n";
104
- fs.writeFileSync(tempFile, beforeYaml);
105
- const obj = { hello: "world", test: [1, 2, 3] };
106
- const output = yml_1.ymlParser.stringify(obj, tempFile);
107
- expect(output).toBe(afterYaml);
108
- });
109
- it("should throw if trying to set YAML document root to a primitive", () => {
110
- const beforeYaml = `
111
- foo: bar
112
- `.trim() + "\n";
113
- fs.writeFileSync(tempFile, beforeYaml);
114
- // Root must be an object when using filePath; primitives throw
115
- expect(() => {
116
- yml_1.ymlParser.stringify("primitive", tempFile);
117
- }).toThrow(/Cannot set root document to a primitive value/);
118
- });
119
- it("should fall back to simple stringify if filePath does not exist", () => {
120
- const fakeFilePath = path.join(os.tmpdir(), `notfound_${Math.random()}.yml`);
121
- const afterYaml = `
122
- only: in-memory
123
- `.trim() + "\n";
124
- const obj = { only: "in-memory" };
125
- const output = yml_1.ymlParser.stringify(obj, fakeFilePath);
126
- expect(output).toBe(afterYaml);
127
- expect(fs.existsSync(fakeFilePath)).toBe(false); // should not create the file
128
- });
129
- it("should not mutate the original YAML file", () => {
130
- const beforeYaml = `
131
- foo: unchanged
132
- bar: before
133
- `.trim() + "\n";
134
- fs.writeFileSync(tempFile, beforeYaml);
135
- const onDiskBefore = fs.readFileSync(tempFile, "utf8");
136
- const obj = { bar: "after" };
137
- yml_1.ymlParser.stringify(obj, tempFile);
138
- const onDiskAfter = fs.readFileSync(tempFile, "utf8");
139
- expect(onDiskAfter).toBe(onDiskBefore); // file on disk unchanged
140
- });
141
- });
142
- });
143
- //# sourceMappingURL=yml.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"yml.spec.js","sourceRoot":"","sources":["../../src/parsers/yml.spec.ts"],"names":[],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- import { jsonParser } from "./json";
2
- import { ymlParser } from "./yml";
3
-
4
- export interface CustomParser {
5
- extension: string;
6
- parse: <T>(content: string, filePath?: string) => T;
7
- stringify: (content: any, filePath?: string) => string;
8
- }
9
-
10
- /**
11
- * If we want to add more built-in parsers,
12
- * add them to this object with new file extension as the key,
13
- * and a function that takes file content as string and returns parsed object as the value.
14
- */
15
- export const parsers: { [key: string]: CustomParser } = {
16
- yml: ymlParser,
17
- json: jsonParser,
18
- };
19
-
20
- export type BuiltInParser = keyof typeof parsers; // keys of parsers object
21
-
22
- export type Parser = BuiltInParser | CustomParser;
@@ -1,36 +0,0 @@
1
- import { jsonParser } from "./json";
2
-
3
- describe("core :: parser :: jsonParser", () => {
4
- it("should parse JSON string into object", () => {
5
- const jsonString = '{"foo":1,"bar":"baz","arr":[1,2]}';
6
- const result = jsonParser.parse<{ foo: number; bar: string; arr: number[] }>(jsonString);
7
- expect(result).toEqual({ foo: 1, bar: "baz", arr: [1, 2] });
8
- });
9
-
10
- it("should stringify object into JSON string (pretty-printed)", () => {
11
- const obj = { foo: 1, bar: "baz", arr: [1, 2] };
12
- const jsonString = jsonParser.stringify(obj);
13
- const expectedString = `{
14
- "foo": 1,
15
- "bar": "baz",
16
- "arr": [
17
- 1,
18
- 2
19
- ]
20
- }`;
21
- expect(jsonString).toBe(expectedString);
22
- });
23
-
24
- it("should parse and then stringify to preserve content", () => {
25
- const original = { alpha: "a", num: 42, bool: true, nullish: null, nested: { z: "x" } };
26
- const str = jsonParser.stringify(original);
27
- const reparsed = jsonParser.parse<typeof original>(str);
28
- expect(reparsed).toEqual(original);
29
- });
30
-
31
- it("should throw if invalid JSON string is provided to parse", () => {
32
- expect(() => {
33
- jsonParser.parse("this is not json");
34
- }).toThrow();
35
- });
36
- });
@@ -1,11 +0,0 @@
1
- import type { CustomParser } from "./index";
2
-
3
- export const jsonParser: CustomParser = {
4
- extension: "json",
5
- parse: function <T>(content: string): T {
6
- return JSON.parse(content) as T;
7
- },
8
- stringify: function (content: any) {
9
- return JSON.stringify(content, null, 2);
10
- },
11
- };
@@ -1,174 +0,0 @@
1
- import { ymlParser } from "./yml";
2
-
3
- describe("core :: parser :: ymlParser", () => {
4
- it("should parse YAML string into object", () => {
5
- const yamlString = `
6
- foo: 1
7
- bar: baz
8
- arr:
9
- - 1
10
- - 2
11
- `;
12
- const result = ymlParser.parse<{ foo: number; bar: string; arr: number[] }>(yamlString);
13
- expect(result).toEqual({ foo: 1, bar: "baz", arr: [1, 2] });
14
- });
15
-
16
- it("should stringify object into YAML string", () => {
17
- const obj = { foo: 1, bar: "baz", arr: [1, 2] };
18
- const yamlString = ymlParser.stringify(obj);
19
- expect(yamlString.trim()).toBe(`foo: 1
20
- bar: baz
21
- arr:
22
- - 1
23
- - 2`);
24
- });
25
-
26
- it("should parse and then stringify to preserve YAML content semantically", () => {
27
- const original = {
28
- alpha: "a",
29
- num: 42,
30
- bool: true,
31
- nullish: null,
32
- nested: { z: "x", y: [1, 2] },
33
- };
34
- const str = ymlParser.stringify(original);
35
- const reparsed = ymlParser.parse<typeof original>(str);
36
- expect(reparsed).toEqual(original);
37
- });
38
-
39
- it("should throw if invalid YAML string is provided to parse", () => {
40
- expect(() => {
41
- ymlParser.parse("foo: : bar");
42
- }).toThrow();
43
- });
44
-
45
- describe("stringify() with filePath argument (existing file for ordering/comments only)", () => {
46
- const fs = require("fs");
47
- const path = require("path");
48
- const os = require("os");
49
-
50
- let tempFile: string;
51
-
52
- beforeEach(() => {
53
- tempFile = path.join(os.tmpdir(), `test_${Math.random()}.yml`);
54
- });
55
-
56
- afterEach(() => {
57
- if (fs.existsSync(tempFile)) {
58
- fs.unlinkSync(tempFile);
59
- }
60
- });
61
-
62
- it("should save exactly the new object; existing file is only for ordering/comments", () => {
63
- const beforeYaml =
64
- `
65
- foo: 1 # foo comment here
66
- extra: blah
67
-
68
- ##
69
- # Comment above nested
70
- #
71
- nested:
72
- a: x
73
- b: y # b comment
74
- array:
75
- - one # one
76
- - two # two
77
- - three # three
78
- `.trim() + "\n";
79
-
80
- const newContent = {
81
- foo: 42,
82
- bar: "new",
83
- nested: { b: "updated", c: "added" },
84
- array: ["two", "three", "four"],
85
- };
86
-
87
- const afterYaml =
88
- `
89
- foo: 42 # foo comment here
90
- bar: new
91
- ##
92
- # Comment above nested
93
- #
94
- nested:
95
- b: updated # b comment
96
- c: added
97
- array:
98
- - two # two
99
- - three # three
100
- - four
101
- `.trim() + "\n";
102
-
103
- fs.writeFileSync(tempFile, beforeYaml);
104
-
105
- const output = ymlParser.stringify(newContent, tempFile);
106
-
107
- expect(output).toBe(afterYaml);
108
- });
109
-
110
- it("should replace the root if YAML file is empty", () => {
111
- const beforeYaml = "";
112
- const afterYaml =
113
- `
114
- hello: world
115
- test:
116
- - 1
117
- - 2
118
- - 3
119
- `.trim() + "\n";
120
-
121
- fs.writeFileSync(tempFile, beforeYaml);
122
-
123
- const obj = { hello: "world", test: [1, 2, 3] };
124
- const output = ymlParser.stringify(obj, tempFile);
125
-
126
- expect(output).toBe(afterYaml);
127
- });
128
-
129
- it("should throw if trying to set YAML document root to a primitive", () => {
130
- const beforeYaml =
131
- `
132
- foo: bar
133
- `.trim() + "\n";
134
-
135
- fs.writeFileSync(tempFile, beforeYaml);
136
-
137
- // Root must be an object when using filePath; primitives throw
138
- expect(() => {
139
- ymlParser.stringify("primitive", tempFile);
140
- }).toThrow(/Cannot set root document to a primitive value/);
141
- });
142
-
143
- it("should fall back to simple stringify if filePath does not exist", () => {
144
- const fakeFilePath = path.join(os.tmpdir(), `notfound_${Math.random()}.yml`);
145
- const afterYaml =
146
- `
147
- only: in-memory
148
- `.trim() + "\n";
149
-
150
- const obj = { only: "in-memory" };
151
- const output = ymlParser.stringify(obj, fakeFilePath);
152
-
153
- expect(output).toBe(afterYaml);
154
- expect(fs.existsSync(fakeFilePath)).toBe(false); // should not create the file
155
- });
156
-
157
- it("should not mutate the original YAML file", () => {
158
- const beforeYaml =
159
- `
160
- foo: unchanged
161
- bar: before
162
- `.trim() + "\n";
163
-
164
- fs.writeFileSync(tempFile, beforeYaml);
165
- const onDiskBefore = fs.readFileSync(tempFile, "utf8");
166
-
167
- const obj = { bar: "after" };
168
- ymlParser.stringify(obj, tempFile);
169
-
170
- const onDiskAfter = fs.readFileSync(tempFile, "utf8");
171
- expect(onDiskAfter).toBe(onDiskBefore); // file on disk unchanged
172
- });
173
- });
174
- });