@unispechq/unispec-core 0.3.0 → 0.3.2
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.
- package/dist/cjs/diff/annotators.js +36 -9
- package/dist/cjs/src/cache/cache-factory.js +72 -0
- package/dist/cjs/src/cache/cache-manager.js +128 -0
- package/dist/cjs/src/cache/constants.js +25 -0
- package/dist/cjs/src/cache/hash-utils.js +19 -0
- package/dist/cjs/src/cache/hashing.js +230 -0
- package/dist/cjs/src/cache/index.js +24 -0
- package/dist/cjs/src/cache/lru-cache.js +144 -0
- package/dist/cjs/src/cache/types.js +5 -0
- package/dist/cjs/src/diff/annotators.js +160 -0
- package/dist/cjs/src/diff/change-reports.js +369 -0
- package/dist/cjs/src/diff/core.js +158 -0
- package/dist/cjs/src/diff/enhanced-diff.js +65 -0
- package/dist/cjs/src/diff/impact-strategies-refactored.js +230 -0
- package/dist/cjs/src/diff/impact-strategies.js +219 -0
- package/dist/cjs/src/diff/index.js +27 -0
- package/dist/cjs/src/diff/metrics-calculator.js +69 -0
- package/dist/cjs/src/diff/risk-calculator.js +58 -0
- package/dist/cjs/src/diff/suggestion-generator.js +78 -0
- package/dist/cjs/src/diff/types.js +11 -0
- package/dist/cjs/src/errors/base-error.js +33 -0
- package/dist/cjs/src/errors/config-error.js +11 -0
- package/dist/cjs/src/errors/error-factory.js +48 -0
- package/dist/cjs/src/errors/index.js +19 -0
- package/dist/cjs/src/errors/loader-error.js +11 -0
- package/dist/cjs/src/errors/reference-error.js +11 -0
- package/dist/cjs/src/errors/schema-error.js +11 -0
- package/dist/cjs/src/errors/security-error.js +11 -0
- package/dist/cjs/src/errors/semantic-error.js +11 -0
- package/dist/cjs/src/generated-schemas.js +2100 -0
- package/dist/cjs/src/index.js +59 -0
- package/dist/cjs/src/loader/index.js +13 -0
- package/dist/cjs/src/loader/security-validator.js +53 -0
- package/dist/cjs/src/loader/types.js +11 -0
- package/dist/cjs/src/loader/unispec-loader.js +84 -0
- package/dist/cjs/src/loader/yaml-loader.js +76 -0
- package/dist/cjs/src/normalizer/core.js +37 -0
- package/dist/cjs/src/normalizer/graphql-normalizer.js +67 -0
- package/dist/cjs/src/normalizer/index.js +7 -0
- package/dist/cjs/src/normalizer/rest-normalizer.js +51 -0
- package/dist/cjs/src/normalizer/types.js +2 -0
- package/dist/cjs/src/normalizer/utils.js +49 -0
- package/dist/cjs/src/normalizer/websocket-normalizer.js +81 -0
- package/dist/cjs/src/optimizer/core.js +140 -0
- package/dist/cjs/src/optimizer/index.js +17 -0
- package/dist/cjs/src/optimizer/optimization-functions.js +185 -0
- package/dist/cjs/src/optimizer/types.js +2 -0
- package/dist/cjs/src/optimizer/utils.js +32 -0
- package/dist/cjs/src/schemas/dedupe.js +113 -0
- package/dist/cjs/src/schemas/index.js +14 -0
- package/dist/cjs/src/schemas/resolver.js +42 -0
- package/dist/cjs/src/schemas/utils.js +53 -0
- package/dist/cjs/src/types/index.js +2 -0
- package/dist/cjs/src/validator/ajv-validator.js +82 -0
- package/dist/cjs/src/validator/config-validator-main.js +34 -0
- package/dist/cjs/src/validator/config-validator.js +17 -0
- package/dist/cjs/src/validator/index.js +23 -0
- package/dist/cjs/src/validator/object-traversal.js +112 -0
- package/dist/cjs/src/validator/reference-validator.js +233 -0
- package/dist/cjs/src/validator/schema-references.js +116 -0
- package/dist/cjs/src/validator/semantic-validator.js +328 -0
- package/dist/cjs/src/validator/tests-validator.js +16 -0
- package/dist/cjs/src/validator/types.js +2 -0
- package/dist/cjs/src/validator/unispec-validator.js +80 -0
- package/dist/cjs/src/validator/validator-factory.js +77 -0
- package/dist/cjs/src/versions.js +147 -0
- package/dist/cjs/tests/cache/cache.test.js +274 -0
- package/dist/cjs/tests/cache/utils.js +32 -0
- package/dist/cjs/tests/concurrency-normalizer-optimizer.test.js +1 -0
- package/dist/cjs/tests/diff/diff-annotators.test.js +280 -0
- package/dist/cjs/tests/diff/diff-comprehensive.test.js +262 -0
- package/dist/cjs/tests/diff/diff-extended.test.js +235 -0
- package/dist/cjs/tests/diff/diff.test.js +189 -0
- package/dist/cjs/tests/diff/utils.js +8 -0
- package/dist/cjs/tests/errors/errors-integration.test.js +173 -0
- package/dist/cjs/tests/errors/errors.test.js +280 -0
- package/dist/cjs/tests/errors/utils.js +7 -0
- package/dist/cjs/tests/loader/integration.test.js +216 -0
- package/dist/cjs/tests/loader/loader.test.js +341 -0
- package/dist/cjs/tests/normalizer/normalizer-comprehensive.test.js +648 -0
- package/dist/cjs/tests/normalizer/normalizer-invalid.test.js +258 -0
- package/dist/cjs/tests/normalizer/normalizer-valid.test.js +238 -0
- package/dist/cjs/tests/normalizer/utils.js +47 -0
- package/dist/cjs/tests/optimizer/compress-references.test.js +304 -0
- package/dist/cjs/tests/optimizer/deduplication.test.js +132 -0
- package/dist/cjs/tests/optimizer/integration.test.js +131 -0
- package/dist/cjs/tests/optimizer/optimization-report.test.js +222 -0
- package/dist/cjs/tests/optimizer/optimize-document.test.js +187 -0
- package/dist/cjs/tests/optimizer/orphaned-schemas.test.js +194 -0
- package/dist/cjs/tests/optimizer/sort-schemas.test.js +131 -0
- package/dist/cjs/tests/optimizer/utils.js +209 -0
- package/dist/cjs/tests/schemas/schemas-edge-cases.test.js +223 -0
- package/dist/cjs/tests/schemas/schemas.test.js +400 -0
- package/dist/cjs/tests/schemas/utils.js +7 -0
- package/dist/cjs/tests/utils.js +131 -0
- package/dist/cjs/tests/validator/config-validator.test.js +78 -0
- package/dist/cjs/tests/validator/debug-config.js +1 -0
- package/dist/cjs/tests/validator/debug-missing-service.js +1 -0
- package/dist/cjs/tests/validator/debug-other-configs.js +1 -0
- package/dist/cjs/tests/validator/debug-references.js +1 -0
- package/dist/cjs/tests/validator/unispec-validator.test.js +103 -0
- package/dist/cjs/tests/validator/utils.js +25 -0
- package/dist/diff/annotators.js +36 -9
- package/dist/src/cache/cache-factory.d.ts +31 -0
- package/dist/src/cache/cache-factory.js +65 -0
- package/dist/src/cache/cache-manager.d.ts +62 -0
- package/dist/src/cache/cache-manager.js +124 -0
- package/dist/src/cache/constants.d.ts +21 -0
- package/dist/src/cache/constants.js +22 -0
- package/dist/src/cache/hash-utils.d.ts +11 -0
- package/dist/src/cache/hash-utils.js +15 -0
- package/dist/src/cache/hashing.d.ts +28 -0
- package/dist/src/cache/hashing.js +193 -0
- package/dist/src/cache/index.d.ts +6 -0
- package/dist/src/cache/index.js +10 -0
- package/dist/src/cache/lru-cache.d.ts +44 -0
- package/dist/src/cache/lru-cache.js +140 -0
- package/dist/src/cache/types.d.ts +24 -0
- package/dist/src/cache/types.js +4 -0
- package/dist/src/diff/annotators.d.ts +4 -0
- package/dist/src/diff/annotators.js +155 -0
- package/dist/src/diff/change-reports.d.ts +37 -0
- package/dist/src/diff/change-reports.js +366 -0
- package/dist/src/diff/core.d.ts +26 -0
- package/dist/src/diff/core.js +155 -0
- package/dist/src/diff/enhanced-diff.d.ts +51 -0
- package/dist/src/diff/enhanced-diff.js +62 -0
- package/dist/src/diff/impact-strategies-refactored.d.ts +69 -0
- package/dist/src/diff/impact-strategies-refactored.js +223 -0
- package/dist/src/diff/impact-strategies.d.ts +41 -0
- package/dist/src/diff/impact-strategies.js +212 -0
- package/dist/src/diff/index.d.ts +8 -0
- package/dist/src/diff/index.js +11 -0
- package/dist/src/diff/metrics-calculator.d.ts +23 -0
- package/dist/src/diff/metrics-calculator.js +65 -0
- package/dist/src/diff/risk-calculator.d.ts +23 -0
- package/dist/src/diff/risk-calculator.js +55 -0
- package/dist/src/diff/suggestion-generator.d.ts +18 -0
- package/dist/src/diff/suggestion-generator.js +74 -0
- package/dist/src/diff/types.d.ts +24 -0
- package/dist/src/diff/types.js +8 -0
- package/dist/src/errors/base-error.d.ts +20 -0
- package/dist/src/errors/base-error.js +29 -0
- package/dist/src/errors/config-error.d.ts +4 -0
- package/dist/src/errors/config-error.js +7 -0
- package/dist/src/errors/error-factory.d.ts +22 -0
- package/dist/src/errors/error-factory.js +45 -0
- package/dist/src/errors/index.d.ts +8 -0
- package/dist/src/errors/index.js +8 -0
- package/dist/src/errors/loader-error.d.ts +4 -0
- package/dist/src/errors/loader-error.js +7 -0
- package/dist/src/errors/reference-error.d.ts +4 -0
- package/dist/src/errors/reference-error.js +7 -0
- package/dist/src/errors/schema-error.d.ts +4 -0
- package/dist/src/errors/schema-error.js +7 -0
- package/dist/src/errors/security-error.d.ts +4 -0
- package/dist/src/errors/security-error.js +7 -0
- package/dist/src/errors/semantic-error.d.ts +4 -0
- package/dist/src/errors/semantic-error.js +7 -0
- package/dist/src/generated-schemas.d.ts +2073 -0
- package/dist/src/generated-schemas.js +2097 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.js +43 -0
- package/dist/src/loader/index.d.ts +5 -0
- package/dist/src/loader/index.js +5 -0
- package/dist/src/loader/security-validator.d.ts +5 -0
- package/dist/src/loader/security-validator.js +50 -0
- package/dist/src/loader/types.d.ts +30 -0
- package/dist/src/loader/types.js +8 -0
- package/dist/src/loader/unispec-loader.d.ts +10 -0
- package/dist/src/loader/unispec-loader.js +81 -0
- package/dist/src/loader/yaml-loader.d.ts +10 -0
- package/dist/src/loader/yaml-loader.js +39 -0
- package/dist/src/normalizer/core.d.ts +24 -0
- package/dist/src/normalizer/core.js +34 -0
- package/dist/src/normalizer/graphql-normalizer.d.ts +8 -0
- package/dist/src/normalizer/graphql-normalizer.js +64 -0
- package/dist/src/normalizer/index.d.ts +2 -0
- package/dist/src/normalizer/index.js +3 -0
- package/dist/src/normalizer/rest-normalizer.d.ts +8 -0
- package/dist/src/normalizer/rest-normalizer.js +48 -0
- package/dist/src/normalizer/types.d.ts +7 -0
- package/dist/src/normalizer/types.js +1 -0
- package/dist/src/normalizer/utils.d.ts +17 -0
- package/dist/src/normalizer/utils.js +45 -0
- package/dist/src/normalizer/websocket-normalizer.d.ts +8 -0
- package/dist/src/normalizer/websocket-normalizer.js +78 -0
- package/dist/src/optimizer/core.d.ts +17 -0
- package/dist/src/optimizer/core.js +136 -0
- package/dist/src/optimizer/index.d.ts +4 -0
- package/dist/src/optimizer/index.js +7 -0
- package/dist/src/optimizer/optimization-functions.d.ts +32 -0
- package/dist/src/optimizer/optimization-functions.js +179 -0
- package/dist/src/optimizer/types.d.ts +28 -0
- package/dist/src/optimizer/types.js +1 -0
- package/dist/src/optimizer/utils.d.ts +7 -0
- package/dist/src/optimizer/utils.js +29 -0
- package/dist/src/schemas/dedupe.d.ts +9 -0
- package/dist/src/schemas/dedupe.js +110 -0
- package/dist/src/schemas/index.d.ts +3 -0
- package/dist/src/schemas/index.js +6 -0
- package/dist/src/schemas/resolver.d.ts +19 -0
- package/dist/src/schemas/resolver.js +38 -0
- package/dist/src/schemas/utils.d.ts +20 -0
- package/dist/src/schemas/utils.js +49 -0
- package/dist/src/types/index.d.ts +434 -0
- package/dist/src/types/index.js +1 -0
- package/dist/src/validator/ajv-validator.d.ts +15 -0
- package/dist/src/validator/ajv-validator.js +75 -0
- package/dist/src/validator/config-validator-main.d.ts +10 -0
- package/dist/src/validator/config-validator-main.js +31 -0
- package/dist/src/validator/config-validator.d.ts +5 -0
- package/dist/src/validator/config-validator.js +14 -0
- package/dist/src/validator/index.d.ts +10 -0
- package/dist/src/validator/index.js +11 -0
- package/dist/src/validator/object-traversal.d.ts +52 -0
- package/dist/src/validator/object-traversal.js +104 -0
- package/dist/src/validator/reference-validator.d.ts +31 -0
- package/dist/src/validator/reference-validator.js +230 -0
- package/dist/src/validator/schema-references.d.ts +23 -0
- package/dist/src/validator/schema-references.js +111 -0
- package/dist/src/validator/semantic-validator.d.ts +26 -0
- package/dist/src/validator/semantic-validator.js +325 -0
- package/dist/src/validator/tests-validator.d.ts +9 -0
- package/dist/src/validator/tests-validator.js +13 -0
- package/dist/src/validator/types.d.ts +29 -0
- package/dist/src/validator/types.js +1 -0
- package/dist/src/validator/unispec-validator.d.ts +15 -0
- package/dist/src/validator/unispec-validator.js +77 -0
- package/dist/src/validator/validator-factory.d.ts +10 -0
- package/dist/src/validator/validator-factory.js +73 -0
- package/dist/src/versions.d.ts +10 -0
- package/dist/src/versions.js +143 -0
- package/dist/tests/cache/cache.test.d.ts +1 -0
- package/dist/tests/cache/cache.test.js +269 -0
- package/dist/tests/cache/utils.d.ts +4 -0
- package/dist/tests/cache/utils.js +24 -0
- package/dist/tests/concurrency-normalizer-optimizer.test.d.ts +0 -0
- package/dist/tests/concurrency-normalizer-optimizer.test.js +1 -0
- package/dist/tests/diff/diff-annotators.test.d.ts +1 -0
- package/dist/tests/diff/diff-annotators.test.js +275 -0
- package/dist/tests/diff/diff-comprehensive.test.d.ts +1 -0
- package/dist/tests/diff/diff-comprehensive.test.js +257 -0
- package/dist/tests/diff/diff-extended.test.d.ts +1 -0
- package/dist/tests/diff/diff-extended.test.js +230 -0
- package/dist/tests/diff/diff.test.d.ts +1 -0
- package/dist/tests/diff/diff.test.js +184 -0
- package/dist/tests/diff/utils.d.ts +2 -0
- package/dist/tests/diff/utils.js +3 -0
- package/dist/tests/errors/errors-integration.test.d.ts +1 -0
- package/dist/tests/errors/errors-integration.test.js +168 -0
- package/dist/tests/errors/errors.test.d.ts +1 -0
- package/dist/tests/errors/errors.test.js +275 -0
- package/dist/tests/errors/utils.d.ts +2 -0
- package/dist/tests/errors/utils.js +3 -0
- package/dist/tests/loader/integration.test.d.ts +1 -0
- package/dist/tests/loader/integration.test.js +211 -0
- package/dist/tests/loader/loader.test.d.ts +1 -0
- package/dist/tests/loader/loader.test.js +336 -0
- package/dist/tests/normalizer/normalizer-comprehensive.test.d.ts +1 -0
- package/dist/tests/normalizer/normalizer-comprehensive.test.js +643 -0
- package/dist/tests/normalizer/normalizer-invalid.test.d.ts +1 -0
- package/dist/tests/normalizer/normalizer-invalid.test.js +253 -0
- package/dist/tests/normalizer/normalizer-valid.test.d.ts +1 -0
- package/dist/tests/normalizer/normalizer-valid.test.js +233 -0
- package/dist/tests/normalizer/utils.d.ts +18 -0
- package/dist/tests/normalizer/utils.js +36 -0
- package/dist/tests/optimizer/compress-references.test.d.ts +1 -0
- package/dist/tests/optimizer/compress-references.test.js +299 -0
- package/dist/tests/optimizer/deduplication.test.d.ts +1 -0
- package/dist/tests/optimizer/deduplication.test.js +127 -0
- package/dist/tests/optimizer/integration.test.d.ts +1 -0
- package/dist/tests/optimizer/integration.test.js +126 -0
- package/dist/tests/optimizer/optimization-report.test.d.ts +1 -0
- package/dist/tests/optimizer/optimization-report.test.js +217 -0
- package/dist/tests/optimizer/optimize-document.test.d.ts +1 -0
- package/dist/tests/optimizer/optimize-document.test.js +182 -0
- package/dist/tests/optimizer/orphaned-schemas.test.d.ts +1 -0
- package/dist/tests/optimizer/orphaned-schemas.test.js +189 -0
- package/dist/tests/optimizer/sort-schemas.test.d.ts +1 -0
- package/dist/tests/optimizer/sort-schemas.test.js +126 -0
- package/dist/tests/optimizer/utils.d.ts +8 -0
- package/dist/tests/optimizer/utils.js +199 -0
- package/dist/tests/schemas/schemas-edge-cases.test.d.ts +1 -0
- package/dist/tests/schemas/schemas-edge-cases.test.js +218 -0
- package/dist/tests/schemas/schemas.test.d.ts +1 -0
- package/dist/tests/schemas/schemas.test.js +395 -0
- package/dist/tests/schemas/utils.d.ts +2 -0
- package/dist/tests/schemas/utils.js +3 -0
- package/dist/tests/utils.d.ts +10 -0
- package/dist/tests/utils.js +118 -0
- package/dist/tests/validator/config-validator.test.d.ts +1 -0
- package/dist/tests/validator/config-validator.test.js +73 -0
- package/dist/tests/validator/debug-config.d.ts +0 -0
- package/dist/tests/validator/debug-config.js +1 -0
- package/dist/tests/validator/debug-missing-service.d.ts +0 -0
- package/dist/tests/validator/debug-missing-service.js +1 -0
- package/dist/tests/validator/debug-other-configs.d.ts +0 -0
- package/dist/tests/validator/debug-other-configs.js +1 -0
- package/dist/tests/validator/debug-references.d.ts +0 -0
- package/dist/tests/validator/debug-references.js +1 -0
- package/dist/tests/validator/unispec-validator.test.d.ts +1 -0
- package/dist/tests/validator/unispec-validator.test.js +98 -0
- package/dist/tests/validator/utils.d.ts +6 -0
- package/dist/tests/validator/utils.js +20 -0
- package/package.json +4 -3
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_test_1 = require("node:test");
|
|
9
|
+
const utils_1 = require("../../tests/utils.js");
|
|
10
|
+
const core_1 = require("../../src/diff/core.js");
|
|
11
|
+
(0, node_test_1.describe)("diff module - comprehensive schema examples", () => {
|
|
12
|
+
(0, node_test_1.describe)("valid spec examples", () => {
|
|
13
|
+
(0, node_test_1.it)("should handle rest-simple.json correctly", () => {
|
|
14
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
|
|
15
|
+
// Test self-comparison
|
|
16
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
17
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
18
|
+
// Test modifications
|
|
19
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
20
|
+
modified.service.protocols.rest.routes.push({
|
|
21
|
+
name: "newRoute",
|
|
22
|
+
method: "DELETE",
|
|
23
|
+
path: "/users/{id}",
|
|
24
|
+
responses: { 204: { description: "No content" } },
|
|
25
|
+
});
|
|
26
|
+
const diffResult = (0, core_1.diffUniSpec)(doc, modified);
|
|
27
|
+
const newRoute = diffResult.changes.find((change) => change.path.includes("newRoute"));
|
|
28
|
+
node_assert_1.default.ok(newRoute);
|
|
29
|
+
node_assert_1.default.strictEqual(newRoute.protocol, "rest");
|
|
30
|
+
node_assert_1.default.strictEqual(newRoute.severity, "non-breaking");
|
|
31
|
+
});
|
|
32
|
+
(0, node_test_1.it)("should handle graphql-simple.json correctly", () => {
|
|
33
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "graphql-simple.json"));
|
|
34
|
+
// Test self-comparison
|
|
35
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
36
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
37
|
+
// Test schema change
|
|
38
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
39
|
+
modified.service.protocols.graphql.schema +=
|
|
40
|
+
" type NewType { field: String! }";
|
|
41
|
+
const diffResult = (0, core_1.diffUniSpec)(doc, modified);
|
|
42
|
+
const schemaChange = diffResult.changes.find((change) => change.path.includes("schema"));
|
|
43
|
+
node_assert_1.default.ok(schemaChange);
|
|
44
|
+
node_assert_1.default.strictEqual(schemaChange.description, "Value changed");
|
|
45
|
+
});
|
|
46
|
+
(0, node_test_1.it)("should handle websocket-simple.json correctly", () => {
|
|
47
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "websocket-simple.json"));
|
|
48
|
+
// Test self-comparison
|
|
49
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
50
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
51
|
+
// Test channel addition
|
|
52
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
53
|
+
modified.service.protocols.websocket.channels.push({
|
|
54
|
+
name: "newChannel",
|
|
55
|
+
description: "New channel",
|
|
56
|
+
messages: [],
|
|
57
|
+
});
|
|
58
|
+
const diffResult = (0, core_1.diffUniSpec)(doc, modified);
|
|
59
|
+
const newChannel = diffResult.changes.find((change) => change.path.includes("newChannel"));
|
|
60
|
+
node_assert_1.default.ok(newChannel);
|
|
61
|
+
node_assert_1.default.strictEqual(newChannel.protocol, "websocket");
|
|
62
|
+
node_assert_1.default.strictEqual(newChannel.severity, "non-breaking");
|
|
63
|
+
});
|
|
64
|
+
(0, node_test_1.it)("should handle mixed-complete.json correctly", () => {
|
|
65
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "mixed-complete.json"));
|
|
66
|
+
// Test self-comparison
|
|
67
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
68
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
69
|
+
// Test multiple protocol changes
|
|
70
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
71
|
+
// Add REST route
|
|
72
|
+
if (modified.service.protocols.rest) {
|
|
73
|
+
modified.service.protocols.rest.routes.push({
|
|
74
|
+
name: "mixedRoute",
|
|
75
|
+
method: "PATCH",
|
|
76
|
+
path: "/mixed",
|
|
77
|
+
responses: { 200: { description: "OK" } },
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Add GraphQL query
|
|
81
|
+
if (modified.service.protocols.graphql?.queries) {
|
|
82
|
+
modified.service.protocols.graphql.queries.push({
|
|
83
|
+
name: "mixedQuery",
|
|
84
|
+
description: "Mixed query",
|
|
85
|
+
args: [],
|
|
86
|
+
returnType: "String",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const diffResult = (0, core_1.diffUniSpec)(doc, modified);
|
|
90
|
+
// Should have both REST and GraphQL changes
|
|
91
|
+
const restChanges = diffResult.changes.filter((change) => change.protocol === "rest");
|
|
92
|
+
const graphqlChanges = diffResult.changes.filter((change) => change.protocol === "graphql");
|
|
93
|
+
node_assert_1.default.ok(restChanges.length > 0);
|
|
94
|
+
node_assert_1.default.ok(graphqlChanges.length > 0);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
(0, node_test_1.describe)("valid config examples", () => {
|
|
98
|
+
(0, node_test_1.it)("should handle complete-enterprise.json correctly", () => {
|
|
99
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "complete-enterprise.json"));
|
|
100
|
+
// Test self-comparison
|
|
101
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
102
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
103
|
+
// Test modification
|
|
104
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
105
|
+
if (Array.isArray(modified.services)) {
|
|
106
|
+
modified.services.push({
|
|
107
|
+
name: "new-service",
|
|
108
|
+
baseUrl: "https://new-service.example.com",
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const diffResult = (0, core_1.diffUniSpec)(doc, modified);
|
|
112
|
+
node_assert_1.default.ok(diffResult.changes.length > 0);
|
|
113
|
+
});
|
|
114
|
+
(0, node_test_1.it)("should handle registry-based.json correctly", () => {
|
|
115
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "registry-based.json"));
|
|
116
|
+
// Test self-comparison
|
|
117
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
118
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
119
|
+
});
|
|
120
|
+
(0, node_test_1.it)("should handle simple-multi-service.json correctly", () => {
|
|
121
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "simple-multi-service.json"));
|
|
122
|
+
// Test self-comparison
|
|
123
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
124
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
(0, node_test_1.describe)("invalid spec examples", () => {
|
|
128
|
+
(0, node_test_1.it)("should handle graphql-missing-arg-type.json without crashing", () => {
|
|
129
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "graphql-missing-arg-type.json"));
|
|
130
|
+
// Should not crash on invalid documents
|
|
131
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
132
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
133
|
+
// Should handle modifications
|
|
134
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
135
|
+
modified.unispecVersion = "1.0.1";
|
|
136
|
+
const diffResult = (0, core_1.diffUniSpec)(doc, modified);
|
|
137
|
+
const versionChange = diffResult.changes.find((change) => change.path === "/unispecVersion");
|
|
138
|
+
node_assert_1.default.ok(versionChange);
|
|
139
|
+
});
|
|
140
|
+
(0, node_test_1.it)("should handle graphql-missing-name.json without crashing", () => {
|
|
141
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "graphql-missing-name.json"));
|
|
142
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
143
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
144
|
+
});
|
|
145
|
+
(0, node_test_1.it)("should handle invalid-identifier.json without crashing", () => {
|
|
146
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "invalid-identifier.json"));
|
|
147
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
148
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
149
|
+
});
|
|
150
|
+
(0, node_test_1.it)("should handle invalid-rest-method.json without crashing", () => {
|
|
151
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "invalid-rest-method.json"));
|
|
152
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
153
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
154
|
+
});
|
|
155
|
+
(0, node_test_1.it)("should handle missing-service-name.json without crashing", () => {
|
|
156
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "missing-service-name.json"));
|
|
157
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
158
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
159
|
+
});
|
|
160
|
+
(0, node_test_1.it)("should handle missing-unispec-version.json without crashing", () => {
|
|
161
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "missing-unispec-version.json"));
|
|
162
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
163
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
(0, node_test_1.describe)("invalid config examples", () => {
|
|
167
|
+
(0, node_test_1.it)("should handle empty-services-array.json without crashing", () => {
|
|
168
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "empty-services-array.json"));
|
|
169
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
170
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
171
|
+
});
|
|
172
|
+
(0, node_test_1.it)("should handle invalid-spec-reference.json without crashing", () => {
|
|
173
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "invalid-spec-reference.json"));
|
|
174
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
175
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
176
|
+
});
|
|
177
|
+
(0, node_test_1.it)("should handle missing-services.json without crashing", () => {
|
|
178
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "missing-services.json"));
|
|
179
|
+
const result = (0, core_1.diffUniSpec)(doc, doc);
|
|
180
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
(0, node_test_1.describe)("cross-example comparisons", () => {
|
|
184
|
+
(0, node_test_1.it)("should handle comparing different valid specs", () => {
|
|
185
|
+
const restDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
|
|
186
|
+
const graphqlDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "graphql-simple.json"));
|
|
187
|
+
// Should detect many differences between different specs
|
|
188
|
+
const result = (0, core_1.diffUniSpec)(restDoc, graphqlDoc);
|
|
189
|
+
node_assert_1.default.ok(result.changes.length > 0);
|
|
190
|
+
// Most changes will be structural and not protocol-specific
|
|
191
|
+
// since the documents have completely different structures
|
|
192
|
+
const structuralChanges = result.changes.filter((change) => change.protocol === undefined);
|
|
193
|
+
// Should have some structural changes
|
|
194
|
+
node_assert_1.default.ok(structuralChanges.length > 0);
|
|
195
|
+
// May have some protocol-specific changes if paths overlap
|
|
196
|
+
const restChanges = result.changes.filter((change) => change.protocol === "rest");
|
|
197
|
+
const graphqlChanges = result.changes.filter((change) => change.protocol === "graphql");
|
|
198
|
+
// At least one of them should have changes
|
|
199
|
+
node_assert_1.default.ok(restChanges.length > 0 ||
|
|
200
|
+
graphqlChanges.length > 0 ||
|
|
201
|
+
structuralChanges.length > 0);
|
|
202
|
+
});
|
|
203
|
+
(0, node_test_1.it)("should handle comparing valid and invalid specs", () => {
|
|
204
|
+
const validDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
|
|
205
|
+
const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "missing-service-name.json"));
|
|
206
|
+
// Should handle comparisons without crashing
|
|
207
|
+
const result = (0, core_1.diffUniSpec)(validDoc, invalidDoc);
|
|
208
|
+
node_assert_1.default.ok(result.changes.length > 0);
|
|
209
|
+
});
|
|
210
|
+
(0, node_test_1.it)("should handle comparing config and spec files", () => {
|
|
211
|
+
const configDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "simple-multi-service.json"));
|
|
212
|
+
const specDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
|
|
213
|
+
// Should handle completely different structures
|
|
214
|
+
const result = (0, core_1.diffUniSpec)(configDoc, specDoc);
|
|
215
|
+
node_assert_1.default.ok(result.changes.length > 0);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
(0, node_test_1.describe)("edge cases with real examples", () => {
|
|
219
|
+
(0, node_test_1.it)("should handle deeply nested changes in complex examples", () => {
|
|
220
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "mixed-complete.json"));
|
|
221
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
222
|
+
// Make a deep nested change - find the first route with requestBody
|
|
223
|
+
if (modified.service?.protocols?.rest?.routes) {
|
|
224
|
+
const routeWithBody = modified.service.protocols.rest.routes.find((route) => route.requestBody?.content?.["application/json"]?.schemaRef);
|
|
225
|
+
if (routeWithBody) {
|
|
226
|
+
routeWithBody.requestBody.content["application/json"].schemaRef =
|
|
227
|
+
"NewSchemaRef";
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const result = (0, core_1.diffUniSpec)(doc, modified);
|
|
231
|
+
// Should have some changes
|
|
232
|
+
node_assert_1.default.ok(result.changes.length > 0);
|
|
233
|
+
// Look for any schema-related change
|
|
234
|
+
const schemaChange = result.changes.find((change) => change.path.includes("schemaRef"));
|
|
235
|
+
// If we found a route with schemaRef, it should be detected
|
|
236
|
+
if (doc.service?.protocols?.rest?.routes?.some((route) => route.requestBody?.content?.["application/json"]?.schemaRef)) {
|
|
237
|
+
node_assert_1.default.ok(schemaChange);
|
|
238
|
+
node_assert_1.default.strictEqual(schemaChange.description, "Value changed");
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// If no route had schemaRef, we should still have some changes
|
|
242
|
+
node_assert_1.default.ok(result.changes.length > 0);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
(0, node_test_1.it)("should handle array operations in named collections correctly", () => {
|
|
246
|
+
const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
|
|
247
|
+
const modified = JSON.parse(JSON.stringify(doc));
|
|
248
|
+
// Reorder routes array
|
|
249
|
+
if (modified.service.protocols.rest.routes.length >= 2) {
|
|
250
|
+
const temp = modified.service.protocols.rest.routes[0];
|
|
251
|
+
modified.service.protocols.rest.routes[0] =
|
|
252
|
+
modified.service.protocols.rest.routes[1];
|
|
253
|
+
modified.service.protocols.rest.routes[1] = temp;
|
|
254
|
+
}
|
|
255
|
+
const result = (0, core_1.diffUniSpec)(doc, modified);
|
|
256
|
+
// Named collections should compare by name, not index
|
|
257
|
+
// So reordering should not produce changes
|
|
258
|
+
const routeChanges = result.changes.filter((change) => change.path.includes("/routes/"));
|
|
259
|
+
node_assert_1.default.strictEqual(routeChanges.length, 0);
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_test_1 = require("node:test");
|
|
9
|
+
const utils_1 = require("../../tests/utils.js");
|
|
10
|
+
const core_1 = require("../../src/diff/core.js");
|
|
11
|
+
(0, node_test_1.describe)("diff module - extended tests", () => {
|
|
12
|
+
(0, node_test_1.describe)("handling of invalid examples", () => {
|
|
13
|
+
(0, node_test_1.it)("should handle empty services array without crashing", () => {
|
|
14
|
+
const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "empty-services-array.json"));
|
|
15
|
+
// Should not crash when processing invalid documents
|
|
16
|
+
const result = (0, core_1.diffUniSpec)(invalidDoc, invalidDoc);
|
|
17
|
+
node_assert_1.default.strictEqual(result.changes.length, 0);
|
|
18
|
+
});
|
|
19
|
+
(0, node_test_1.it)("should handle missing service name", () => {
|
|
20
|
+
const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "missing-service-name.json"));
|
|
21
|
+
const modifiedDoc = JSON.parse(JSON.stringify(invalidDoc));
|
|
22
|
+
// This is a config file, not a spec, so it has different structure
|
|
23
|
+
modifiedDoc.version = 2;
|
|
24
|
+
const result = (0, core_1.diffUniSpec)(invalidDoc, modifiedDoc);
|
|
25
|
+
node_assert_1.default.ok(result.changes.length > 0);
|
|
26
|
+
const versionChange = result.changes.find((change) => change.path === "/version");
|
|
27
|
+
node_assert_1.default.ok(versionChange);
|
|
28
|
+
node_assert_1.default.strictEqual(versionChange.description, "Value changed");
|
|
29
|
+
});
|
|
30
|
+
(0, node_test_1.it)("should handle missing version", () => {
|
|
31
|
+
const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "missing-version.json"));
|
|
32
|
+
const modifiedDoc = JSON.parse(JSON.stringify(invalidDoc));
|
|
33
|
+
modifiedDoc.service = {
|
|
34
|
+
...modifiedDoc.service,
|
|
35
|
+
description: "Added description",
|
|
36
|
+
};
|
|
37
|
+
const result = (0, core_1.diffUniSpec)(invalidDoc, modifiedDoc);
|
|
38
|
+
node_assert_1.default.ok(result.changes.length > 0);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
(0, node_test_1.describe)("complex scenarios with valid examples", () => {
|
|
42
|
+
(0, node_test_1.it)("should handle mixed protocol changes", () => {
|
|
43
|
+
const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "mixed-complete.json"));
|
|
44
|
+
const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
|
|
45
|
+
// Add REST route
|
|
46
|
+
modifiedDoc.service.protocols.rest.routes.push({
|
|
47
|
+
name: "newRoute",
|
|
48
|
+
summary: "New route",
|
|
49
|
+
path: "/new",
|
|
50
|
+
method: "GET",
|
|
51
|
+
responses: { 200: { description: "Success" } },
|
|
52
|
+
});
|
|
53
|
+
// Add GraphQL query
|
|
54
|
+
if (modifiedDoc.service.protocols.graphql) {
|
|
55
|
+
modifiedDoc.service.protocols.graphql.queries.push({
|
|
56
|
+
name: "newQuery",
|
|
57
|
+
description: "New query",
|
|
58
|
+
args: [],
|
|
59
|
+
returnType: "String",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
63
|
+
const restChange = result.changes.find((change) => change.path.includes("newRoute") && change.protocol === "rest");
|
|
64
|
+
node_assert_1.default.ok(restChange);
|
|
65
|
+
node_assert_1.default.strictEqual(restChange.severity, "non-breaking");
|
|
66
|
+
if (modifiedDoc.service.protocols.graphql) {
|
|
67
|
+
const graphqlChange = result.changes.find((change) => change.path.includes("newQuery") && change.protocol === "graphql");
|
|
68
|
+
node_assert_1.default.ok(graphqlChange);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
(0, node_test_1.it)("should detect breaking changes in REST", () => {
|
|
72
|
+
const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
|
|
73
|
+
const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
|
|
74
|
+
// Remove a route (breaking change)
|
|
75
|
+
modifiedDoc.service.protocols.rest.routes =
|
|
76
|
+
modifiedDoc.service.protocols.rest.routes.filter((route) => route.name !== "getUsers");
|
|
77
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
78
|
+
const removedRoute = result.changes.find((change) => change.path === "/service/protocols/rest/routes/getUsers");
|
|
79
|
+
node_assert_1.default.ok(removedRoute);
|
|
80
|
+
node_assert_1.default.strictEqual(removedRoute.severity, "breaking");
|
|
81
|
+
node_assert_1.default.strictEqual(removedRoute.kind, "rest.route.removed");
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
(0, node_test_1.describe)("edge cases and boundary conditions", () => {
|
|
85
|
+
(0, node_test_1.it)("should handle null vs undefined values", () => {
|
|
86
|
+
const baseDoc = {
|
|
87
|
+
unispecVersion: "1.0.0",
|
|
88
|
+
service: {
|
|
89
|
+
name: "test-service",
|
|
90
|
+
description: undefined,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
const modifiedDoc = {
|
|
94
|
+
unispecVersion: "1.0.0",
|
|
95
|
+
service: {
|
|
96
|
+
name: "test-service",
|
|
97
|
+
description: "A description",
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
101
|
+
const descriptionChange = result.changes.find((change) => change.path === "/service/description");
|
|
102
|
+
node_assert_1.default.ok(descriptionChange);
|
|
103
|
+
node_assert_1.default.strictEqual(descriptionChange.description, "Value changed");
|
|
104
|
+
});
|
|
105
|
+
(0, node_test_1.it)("should handle empty objects and arrays", () => {
|
|
106
|
+
const baseDoc = {
|
|
107
|
+
unispecVersion: "1.0.0",
|
|
108
|
+
service: {
|
|
109
|
+
name: "test-service",
|
|
110
|
+
protocols: {
|
|
111
|
+
rest: {
|
|
112
|
+
routes: [],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
const modifiedDoc = {
|
|
118
|
+
unispecVersion: "1.0.0",
|
|
119
|
+
service: {
|
|
120
|
+
name: "test-service",
|
|
121
|
+
protocols: {
|
|
122
|
+
rest: {
|
|
123
|
+
routes: [
|
|
124
|
+
{
|
|
125
|
+
name: "newRoute",
|
|
126
|
+
method: "GET",
|
|
127
|
+
path: "/test",
|
|
128
|
+
responses: { 200: { description: "OK" } },
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
136
|
+
const routeChange = result.changes.find((change) => change.path === "/service/protocols/rest/routes/newRoute");
|
|
137
|
+
node_assert_1.default.ok(routeChange);
|
|
138
|
+
node_assert_1.default.strictEqual(routeChange.description, "Item added");
|
|
139
|
+
node_assert_1.default.strictEqual(routeChange.protocol, "rest");
|
|
140
|
+
});
|
|
141
|
+
(0, node_test_1.it)("should handle deeply nested structures", () => {
|
|
142
|
+
const baseDoc = {
|
|
143
|
+
unispecVersion: "1.0.0",
|
|
144
|
+
service: {
|
|
145
|
+
name: "test-service",
|
|
146
|
+
metadata: {
|
|
147
|
+
tags: [{ name: "api", version: "1.0" }],
|
|
148
|
+
info: {
|
|
149
|
+
contact: {
|
|
150
|
+
email: "test@example.com",
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
|
|
157
|
+
modifiedDoc.service.metadata.tags[0].version = "2.0";
|
|
158
|
+
modifiedDoc.service.metadata.info.contact.phone = "+1234567890";
|
|
159
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
160
|
+
const versionChange = result.changes.find((change) => change.path === "/service/metadata/tags/0/version");
|
|
161
|
+
node_assert_1.default.ok(versionChange);
|
|
162
|
+
node_assert_1.default.strictEqual(versionChange.description, "Value changed");
|
|
163
|
+
const phoneChange = result.changes.find((change) => change.path === "/service/metadata/info/contact/phone");
|
|
164
|
+
node_assert_1.default.ok(phoneChange);
|
|
165
|
+
node_assert_1.default.strictEqual(phoneChange.description, "Field added");
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
(0, node_test_1.describe)("array handling", () => {
|
|
169
|
+
(0, node_test_1.it)("should handle regular arrays (non-named collections)", () => {
|
|
170
|
+
const baseDoc = {
|
|
171
|
+
unispecVersion: "1.0.0",
|
|
172
|
+
service: {
|
|
173
|
+
name: "test-service",
|
|
174
|
+
tags: ["api", "v1"],
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
|
|
178
|
+
modifiedDoc.service.tags = ["api", "v2", "production"];
|
|
179
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
180
|
+
// Should detect changes at index level for regular arrays
|
|
181
|
+
const indexChange = result.changes.find((change) => change.path === "/service/tags/1");
|
|
182
|
+
node_assert_1.default.ok(indexChange);
|
|
183
|
+
node_assert_1.default.strictEqual(indexChange.description, "Value changed");
|
|
184
|
+
const addedChange = result.changes.find((change) => change.path === "/service/tags/2");
|
|
185
|
+
node_assert_1.default.ok(addedChange);
|
|
186
|
+
node_assert_1.default.strictEqual(addedChange.description, "Item added");
|
|
187
|
+
});
|
|
188
|
+
(0, node_test_1.it)("should handle arrays without name property", () => {
|
|
189
|
+
const baseDoc = {
|
|
190
|
+
unispecVersion: "1.0.0",
|
|
191
|
+
service: {
|
|
192
|
+
name: "test-service",
|
|
193
|
+
items: [
|
|
194
|
+
{ id: 1, value: "first" },
|
|
195
|
+
{ id: 2, value: "second" },
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
|
|
200
|
+
modifiedDoc.service.items[0].value = "updated";
|
|
201
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
202
|
+
// Should use index-based comparison for arrays without name property
|
|
203
|
+
const itemChange = result.changes.find((change) => change.path === "/service/items/0/value");
|
|
204
|
+
node_assert_1.default.ok(itemChange);
|
|
205
|
+
node_assert_1.default.strictEqual(itemChange.description, "Value changed");
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
(0, node_test_1.describe)("protocol-specific behavior", () => {
|
|
209
|
+
(0, node_test_1.it)("should handle WebSocket messages correctly", () => {
|
|
210
|
+
const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "websocket-simple.json"));
|
|
211
|
+
const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
|
|
212
|
+
// Add message to existing channel
|
|
213
|
+
if (modifiedDoc.service.protocols.websocket.channels[0]) {
|
|
214
|
+
modifiedDoc.service.protocols.websocket.channels[0].messages.push({
|
|
215
|
+
name: "newMessage",
|
|
216
|
+
description: "New message type",
|
|
217
|
+
direction: "publish",
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
221
|
+
const messageChange = result.changes.find((change) => change.path.includes("newMessage") && change.protocol === "websocket");
|
|
222
|
+
node_assert_1.default.ok(messageChange);
|
|
223
|
+
});
|
|
224
|
+
(0, node_test_1.it)("should handle GraphQL schema changes", () => {
|
|
225
|
+
const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "graphql-simple.json"));
|
|
226
|
+
const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
|
|
227
|
+
// Change schema string
|
|
228
|
+
modifiedDoc.service.protocols.graphql.schema = `${baseDoc.service.protocols?.graphql?.schema} type NewType { field: String! }`;
|
|
229
|
+
const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
|
|
230
|
+
const schemaChange = result.changes.find((change) => change.path === "/service/protocols/graphql/schema");
|
|
231
|
+
node_assert_1.default.ok(schemaChange);
|
|
232
|
+
node_assert_1.default.strictEqual(schemaChange.description, "Value changed");
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|