@kya-os/mcp-i-core 1.2.3-canary.6 → 1.3.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.
- package/.claude/settings.local.json +9 -0
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-test$colon$coverage.log +4514 -0
- package/.turbo/turbo-test.log +2973 -0
- package/COMPLIANCE_IMPROVEMENT_REPORT.md +483 -0
- package/Composer 3.md +615 -0
- package/GPT-5.md +1169 -0
- package/OPUS-plan.md +352 -0
- package/PHASE_3_AND_4.1_SUMMARY.md +585 -0
- package/PHASE_3_SUMMARY.md +317 -0
- package/PHASE_4.1.3_SUMMARY.md +428 -0
- package/PHASE_4.1_COMPLETE.md +525 -0
- package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +1240 -0
- package/SCHEMA_COMPLIANCE_REPORT.md +275 -0
- package/TEST_PLAN.md +571 -0
- package/coverage/coverage-final.json +57 -0
- package/dist/__tests__/utils/mock-providers.d.ts +1 -2
- package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
- package/dist/__tests__/utils/mock-providers.js.map +1 -1
- package/dist/cache/oauth-config-cache.d.ts +69 -0
- package/dist/cache/oauth-config-cache.d.ts.map +1 -0
- package/dist/cache/oauth-config-cache.js +76 -0
- package/dist/cache/oauth-config-cache.js.map +1 -0
- package/dist/identity/idp-token-resolver.d.ts +53 -0
- package/dist/identity/idp-token-resolver.d.ts.map +1 -0
- package/dist/identity/idp-token-resolver.js +108 -0
- package/dist/identity/idp-token-resolver.js.map +1 -0
- package/dist/identity/idp-token-storage.interface.d.ts +42 -0
- package/dist/identity/idp-token-storage.interface.d.ts.map +1 -0
- package/dist/identity/idp-token-storage.interface.js +12 -0
- package/dist/identity/idp-token-storage.interface.js.map +1 -0
- package/dist/identity/user-did-manager.d.ts +39 -1
- package/dist/identity/user-did-manager.d.ts.map +1 -1
- package/dist/identity/user-did-manager.js +69 -3
- package/dist/identity/user-did-manager.js.map +1 -1
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/audit-logger.d.ts +37 -0
- package/dist/runtime/audit-logger.d.ts.map +1 -0
- package/dist/runtime/audit-logger.js +9 -0
- package/dist/runtime/audit-logger.js.map +1 -0
- package/dist/runtime/base.d.ts +58 -2
- package/dist/runtime/base.d.ts.map +1 -1
- package/dist/runtime/base.js +266 -11
- package/dist/runtime/base.js.map +1 -1
- package/dist/services/access-control.service.d.ts.map +1 -1
- package/dist/services/access-control.service.js +200 -35
- package/dist/services/access-control.service.js.map +1 -1
- package/dist/services/authorization/authorization-registry.d.ts +29 -0
- package/dist/services/authorization/authorization-registry.d.ts.map +1 -0
- package/dist/services/authorization/authorization-registry.js +57 -0
- package/dist/services/authorization/authorization-registry.js.map +1 -0
- package/dist/services/authorization/types.d.ts +53 -0
- package/dist/services/authorization/types.d.ts.map +1 -0
- package/dist/services/authorization/types.js +10 -0
- package/dist/services/authorization/types.js.map +1 -0
- package/dist/services/batch-delegation.service.d.ts +53 -0
- package/dist/services/batch-delegation.service.d.ts.map +1 -0
- package/dist/services/batch-delegation.service.js +95 -0
- package/dist/services/batch-delegation.service.js.map +1 -0
- package/dist/services/oauth-config.service.d.ts +53 -0
- package/dist/services/oauth-config.service.d.ts.map +1 -0
- package/dist/services/oauth-config.service.js +117 -0
- package/dist/services/oauth-config.service.js.map +1 -0
- package/dist/services/oauth-provider-registry.d.ts +77 -0
- package/dist/services/oauth-provider-registry.d.ts.map +1 -0
- package/dist/services/oauth-provider-registry.js +112 -0
- package/dist/services/oauth-provider-registry.js.map +1 -0
- package/dist/services/oauth-service.d.ts +77 -0
- package/dist/services/oauth-service.d.ts.map +1 -0
- package/dist/services/oauth-service.js +348 -0
- package/dist/services/oauth-service.js.map +1 -0
- package/dist/services/oauth-token-retrieval.service.d.ts +49 -0
- package/dist/services/oauth-token-retrieval.service.d.ts.map +1 -0
- package/dist/services/oauth-token-retrieval.service.js +150 -0
- package/dist/services/oauth-token-retrieval.service.js.map +1 -0
- package/dist/services/provider-resolver.d.ts +48 -0
- package/dist/services/provider-resolver.d.ts.map +1 -0
- package/dist/services/provider-resolver.js +120 -0
- package/dist/services/provider-resolver.js.map +1 -0
- package/dist/services/provider-validator.d.ts +55 -0
- package/dist/services/provider-validator.d.ts.map +1 -0
- package/dist/services/provider-validator.js +135 -0
- package/dist/services/provider-validator.js.map +1 -0
- package/dist/services/tool-context-builder.d.ts +57 -0
- package/dist/services/tool-context-builder.d.ts.map +1 -0
- package/dist/services/tool-context-builder.js +125 -0
- package/dist/services/tool-context-builder.js.map +1 -0
- package/dist/services/tool-protection.service.d.ts +87 -10
- package/dist/services/tool-protection.service.d.ts.map +1 -1
- package/dist/services/tool-protection.service.js +282 -112
- package/dist/services/tool-protection.service.js.map +1 -1
- package/dist/types/oauth-required-error.d.ts +40 -0
- package/dist/types/oauth-required-error.d.ts.map +1 -0
- package/dist/types/oauth-required-error.js +40 -0
- package/dist/types/oauth-required-error.js.map +1 -0
- package/dist/utils/did-helpers.d.ts +33 -0
- package/dist/utils/did-helpers.d.ts.map +1 -1
- package/dist/utils/did-helpers.js +40 -0
- package/dist/utils/did-helpers.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/docs/API_REFERENCE.md +1362 -0
- package/docs/COMPLIANCE_MATRIX.md +691 -0
- package/docs/STATUSLIST2021_GUIDE.md +696 -0
- package/docs/W3C_VC_DELEGATION_GUIDE.md +710 -0
- package/package.json +24 -50
- package/scripts/audit-compliance.ts +724 -0
- package/src/__tests__/cache/tool-protection-cache.test.ts +640 -0
- package/src/__tests__/config/provider-runtime-config.test.ts +309 -0
- package/src/__tests__/delegation-e2e.test.ts +690 -0
- package/src/__tests__/identity/user-did-manager.test.ts +213 -0
- package/src/__tests__/index.test.ts +56 -0
- package/src/__tests__/integration/full-flow.test.ts +776 -0
- package/src/__tests__/integration.test.ts +281 -0
- package/src/__tests__/providers/base.test.ts +173 -0
- package/src/__tests__/providers/memory.test.ts +319 -0
- package/src/__tests__/regression/phase2-regression.test.ts +427 -0
- package/src/__tests__/runtime/audit-logger.test.ts +154 -0
- package/src/__tests__/runtime/base-extensions.test.ts +593 -0
- package/src/__tests__/runtime/base.test.ts +869 -0
- package/src/__tests__/runtime/delegation-flow.test.ts +164 -0
- package/src/__tests__/runtime/proof-client-did.test.ts +375 -0
- package/src/__tests__/runtime/route-interception.test.ts +686 -0
- package/src/__tests__/runtime/tool-protection-enforcement.test.ts +908 -0
- package/src/__tests__/services/agentshield-integration.test.ts +784 -0
- package/src/__tests__/services/provider-resolver-edge-cases.test.ts +487 -0
- package/src/__tests__/services/tool-protection-oauth-provider.test.ts +480 -0
- package/src/__tests__/services/tool-protection.service.test.ts +1366 -0
- package/src/__tests__/utils/mock-providers.ts +340 -0
- package/src/cache/oauth-config-cache.d.ts +69 -0
- package/src/cache/oauth-config-cache.d.ts.map +1 -0
- package/src/cache/oauth-config-cache.js +71 -0
- package/src/cache/oauth-config-cache.js.map +1 -0
- package/src/cache/oauth-config-cache.ts +123 -0
- package/src/cache/tool-protection-cache.ts +171 -0
- package/src/compliance/EXAMPLE.md +412 -0
- package/src/compliance/__tests__/schema-verifier.test.ts +797 -0
- package/src/compliance/index.ts +8 -0
- package/src/compliance/schema-registry.ts +460 -0
- package/src/compliance/schema-verifier.ts +708 -0
- package/src/config/__tests__/remote-config.spec.ts +268 -0
- package/src/config/remote-config.ts +174 -0
- package/src/config.ts +309 -0
- package/src/delegation/__tests__/audience-validator.test.ts +112 -0
- package/src/delegation/__tests__/bitstring.test.ts +346 -0
- package/src/delegation/__tests__/cascading-revocation.test.ts +628 -0
- package/src/delegation/__tests__/delegation-graph.test.ts +584 -0
- package/src/delegation/__tests__/utils.test.ts +152 -0
- package/src/delegation/__tests__/vc-issuer.test.ts +442 -0
- package/src/delegation/__tests__/vc-verifier.test.ts +922 -0
- package/src/delegation/audience-validator.ts +52 -0
- package/src/delegation/bitstring.ts +278 -0
- package/src/delegation/cascading-revocation.ts +370 -0
- package/src/delegation/delegation-graph.ts +299 -0
- package/src/delegation/index.ts +14 -0
- package/src/delegation/statuslist-manager.ts +353 -0
- package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +366 -0
- package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +228 -0
- package/src/delegation/storage/index.ts +9 -0
- package/src/delegation/storage/memory-graph-storage.ts +178 -0
- package/src/delegation/storage/memory-statuslist-storage.ts +77 -0
- package/src/delegation/utils.ts +42 -0
- package/src/delegation/vc-issuer.ts +232 -0
- package/src/delegation/vc-verifier.ts +568 -0
- package/src/identity/idp-token-resolver.ts +147 -0
- package/src/identity/idp-token-storage.interface.ts +59 -0
- package/src/identity/user-did-manager.ts +370 -0
- package/src/index.ts +260 -0
- package/src/providers/base.d.ts +91 -0
- package/src/providers/base.d.ts.map +1 -0
- package/src/providers/base.js +38 -0
- package/src/providers/base.js.map +1 -0
- package/src/providers/base.ts +96 -0
- package/src/providers/memory.ts +142 -0
- package/src/runtime/audit-logger.ts +39 -0
- package/src/runtime/base.ts +1329 -0
- package/src/services/__tests__/access-control.integration.test.ts +443 -0
- package/src/services/__tests__/access-control.proof-response-validation.test.ts +578 -0
- package/src/services/__tests__/access-control.service.test.ts +970 -0
- package/src/services/__tests__/batch-delegation.service.test.ts +351 -0
- package/src/services/__tests__/crypto.service.test.ts +531 -0
- package/src/services/__tests__/oauth-provider-registry.test.ts +142 -0
- package/src/services/__tests__/proof-verifier.integration.test.ts +485 -0
- package/src/services/__tests__/proof-verifier.test.ts +489 -0
- package/src/services/__tests__/provider-resolution.integration.test.ts +198 -0
- package/src/services/__tests__/provider-resolver.test.ts +217 -0
- package/src/services/__tests__/storage.service.test.ts +358 -0
- package/src/services/access-control.service.ts +990 -0
- package/src/services/authorization/authorization-registry.ts +66 -0
- package/src/services/authorization/types.ts +71 -0
- package/src/services/batch-delegation.service.ts +137 -0
- package/src/services/crypto.service.ts +302 -0
- package/src/services/errors.ts +76 -0
- package/src/services/index.ts +9 -0
- package/src/services/oauth-config.service.d.ts +53 -0
- package/src/services/oauth-config.service.d.ts.map +1 -0
- package/src/services/oauth-config.service.js +113 -0
- package/src/services/oauth-config.service.js.map +1 -0
- package/src/services/oauth-config.service.ts +166 -0
- package/src/services/oauth-provider-registry.d.ts +57 -0
- package/src/services/oauth-provider-registry.d.ts.map +1 -0
- package/src/services/oauth-provider-registry.js +73 -0
- package/src/services/oauth-provider-registry.js.map +1 -0
- package/src/services/oauth-provider-registry.ts +123 -0
- package/src/services/oauth-service.ts +510 -0
- package/src/services/oauth-token-retrieval.service.ts +245 -0
- package/src/services/proof-verifier.ts +478 -0
- package/src/services/provider-resolver.d.ts +48 -0
- package/src/services/provider-resolver.d.ts.map +1 -0
- package/src/services/provider-resolver.js +106 -0
- package/src/services/provider-resolver.js.map +1 -0
- package/src/services/provider-resolver.ts +144 -0
- package/src/services/provider-validator.ts +170 -0
- package/src/services/storage.service.ts +566 -0
- package/src/services/tool-context-builder.ts +172 -0
- package/src/services/tool-protection.service.ts +958 -0
- package/src/types/oauth-required-error.ts +63 -0
- package/src/types/tool-protection.ts +155 -0
- package/src/utils/__tests__/did-helpers.test.ts +101 -0
- package/src/utils/base64.ts +148 -0
- package/src/utils/cors.ts +83 -0
- package/src/utils/did-helpers.ts +150 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/storage-keys.ts +278 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +56 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
BitstringManager,
|
|
4
|
+
isIndexSet,
|
|
5
|
+
type CompressionFunction,
|
|
6
|
+
type DecompressionFunction,
|
|
7
|
+
} from "../bitstring.js";
|
|
8
|
+
|
|
9
|
+
// Mock compression functions for testing
|
|
10
|
+
class MockCompressor implements CompressionFunction {
|
|
11
|
+
async compress(data: Uint8Array): Promise<Uint8Array> {
|
|
12
|
+
// Simple mock: just return data as-is (no actual compression)
|
|
13
|
+
return data;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class MockDecompressor implements DecompressionFunction {
|
|
18
|
+
async decompress(data: Uint8Array): Promise<Uint8Array> {
|
|
19
|
+
// Simple mock: just return data as-is
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe("BitstringManager", () => {
|
|
25
|
+
let compressor: CompressionFunction;
|
|
26
|
+
let decompressor: DecompressionFunction;
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
compressor = new MockCompressor();
|
|
30
|
+
decompressor = new MockDecompressor();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("constructor", () => {
|
|
34
|
+
it("should create manager with specified size", () => {
|
|
35
|
+
const manager = new BitstringManager(16, compressor, decompressor);
|
|
36
|
+
expect(manager.getSize()).toBe(16);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should allocate correct number of bytes", () => {
|
|
40
|
+
const manager = new BitstringManager(16, compressor, decompressor);
|
|
41
|
+
// 16 bits = 2 bytes
|
|
42
|
+
expect(manager.getRawBits().length).toBe(2);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should handle size that requires extra byte", () => {
|
|
46
|
+
const manager = new BitstringManager(17, compressor, decompressor);
|
|
47
|
+
// 17 bits = 3 bytes (ceil(17/8) = 3)
|
|
48
|
+
expect(manager.getRawBits().length).toBe(3);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe("setBit", () => {
|
|
53
|
+
it("should set bit to 1", () => {
|
|
54
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
55
|
+
manager.setBit(0, true);
|
|
56
|
+
expect(manager.getBit(0)).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("should set bit to 0", () => {
|
|
60
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
61
|
+
manager.setBit(0, true);
|
|
62
|
+
manager.setBit(0, false);
|
|
63
|
+
expect(manager.getBit(0)).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("should set multiple bits independently", () => {
|
|
67
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
68
|
+
manager.setBit(0, true);
|
|
69
|
+
manager.setBit(2, true);
|
|
70
|
+
manager.setBit(4, true);
|
|
71
|
+
|
|
72
|
+
expect(manager.getBit(0)).toBe(true);
|
|
73
|
+
expect(manager.getBit(1)).toBe(false);
|
|
74
|
+
expect(manager.getBit(2)).toBe(true);
|
|
75
|
+
expect(manager.getBit(3)).toBe(false);
|
|
76
|
+
expect(manager.getBit(4)).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should handle bits across byte boundaries", () => {
|
|
80
|
+
const manager = new BitstringManager(16, compressor, decompressor);
|
|
81
|
+
manager.setBit(7, true); // Last bit of first byte
|
|
82
|
+
manager.setBit(8, true); // First bit of second byte
|
|
83
|
+
|
|
84
|
+
expect(manager.getBit(7)).toBe(true);
|
|
85
|
+
expect(manager.getBit(8)).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should throw error for negative index", () => {
|
|
89
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
90
|
+
expect(() => manager.setBit(-1, true)).toThrow("out of range");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("should throw error for index >= size", () => {
|
|
94
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
95
|
+
expect(() => manager.setBit(8, true)).toThrow("out of range");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe("getBit", () => {
|
|
100
|
+
it("should return false for unset bits", () => {
|
|
101
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
102
|
+
expect(manager.getBit(0)).toBe(false);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("should return true for set bits", () => {
|
|
106
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
107
|
+
manager.setBit(3, true);
|
|
108
|
+
expect(manager.getBit(3)).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should throw error for negative index", () => {
|
|
112
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
113
|
+
expect(() => manager.getBit(-1)).toThrow("out of range");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("should throw error for index >= size", () => {
|
|
117
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
118
|
+
expect(() => manager.getBit(8)).toThrow("out of range");
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe("getSetBits", () => {
|
|
123
|
+
it("should return empty array when no bits are set", () => {
|
|
124
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
125
|
+
expect(manager.getSetBits()).toEqual([]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should return array of set bit indices", () => {
|
|
129
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
130
|
+
manager.setBit(0, true);
|
|
131
|
+
manager.setBit(2, true);
|
|
132
|
+
manager.setBit(5, true);
|
|
133
|
+
|
|
134
|
+
const setBits = manager.getSetBits();
|
|
135
|
+
expect(setBits).toContain(0);
|
|
136
|
+
expect(setBits).toContain(2);
|
|
137
|
+
expect(setBits).toContain(5);
|
|
138
|
+
expect(setBits.length).toBe(3);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("should return indices in order", () => {
|
|
142
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
143
|
+
manager.setBit(5, true);
|
|
144
|
+
manager.setBit(1, true);
|
|
145
|
+
manager.setBit(3, true);
|
|
146
|
+
|
|
147
|
+
const setBits = manager.getSetBits();
|
|
148
|
+
expect(setBits).toEqual([1, 3, 5]);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe("encode", () => {
|
|
153
|
+
it("should encode bitstring to base64url", async () => {
|
|
154
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
155
|
+
manager.setBit(0, true);
|
|
156
|
+
manager.setBit(2, true);
|
|
157
|
+
|
|
158
|
+
const encoded = await manager.encode();
|
|
159
|
+
expect(typeof encoded).toBe("string");
|
|
160
|
+
expect(encoded.length).toBeGreaterThan(0);
|
|
161
|
+
// Base64url should not contain +, /, or =
|
|
162
|
+
expect(encoded).not.toContain("+");
|
|
163
|
+
expect(encoded).not.toContain("/");
|
|
164
|
+
expect(encoded).not.toContain("=");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should produce consistent encoding", async () => {
|
|
168
|
+
const manager1 = new BitstringManager(8, compressor, decompressor);
|
|
169
|
+
manager1.setBit(0, true);
|
|
170
|
+
manager1.setBit(2, true);
|
|
171
|
+
|
|
172
|
+
const manager2 = new BitstringManager(8, compressor, decompressor);
|
|
173
|
+
manager2.setBit(0, true);
|
|
174
|
+
manager2.setBit(2, true);
|
|
175
|
+
|
|
176
|
+
const encoded1 = await manager1.encode();
|
|
177
|
+
const encoded2 = await manager2.encode();
|
|
178
|
+
expect(encoded1).toBe(encoded2);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe("decode", () => {
|
|
183
|
+
it("should decode encoded bitstring", async () => {
|
|
184
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
185
|
+
manager.setBit(0, true);
|
|
186
|
+
manager.setBit(2, true);
|
|
187
|
+
manager.setBit(5, true);
|
|
188
|
+
|
|
189
|
+
const encoded = await manager.encode();
|
|
190
|
+
const decoded = await BitstringManager.decode(
|
|
191
|
+
encoded,
|
|
192
|
+
compressor,
|
|
193
|
+
decompressor
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
expect(decoded.getSize()).toBe(8);
|
|
197
|
+
expect(decoded.getBit(0)).toBe(true);
|
|
198
|
+
expect(decoded.getBit(2)).toBe(true);
|
|
199
|
+
expect(decoded.getBit(5)).toBe(true);
|
|
200
|
+
expect(decoded.getBit(1)).toBe(false);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("should handle round-trip encoding/decoding", async () => {
|
|
204
|
+
const original = new BitstringManager(16, compressor, decompressor);
|
|
205
|
+
original.setBit(0, true);
|
|
206
|
+
original.setBit(7, true);
|
|
207
|
+
original.setBit(8, true);
|
|
208
|
+
original.setBit(15, true);
|
|
209
|
+
|
|
210
|
+
const encoded = await original.encode();
|
|
211
|
+
const decoded = await BitstringManager.decode(
|
|
212
|
+
encoded,
|
|
213
|
+
compressor,
|
|
214
|
+
decompressor
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
expect(decoded.getSize()).toBe(original.getSize());
|
|
218
|
+
for (let i = 0; i < original.getSize(); i++) {
|
|
219
|
+
expect(decoded.getBit(i)).toBe(original.getBit(i));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("fromSetBits", () => {
|
|
225
|
+
it("should create manager from set bit indices", () => {
|
|
226
|
+
const manager = BitstringManager.fromSetBits(
|
|
227
|
+
8,
|
|
228
|
+
[0, 2, 5],
|
|
229
|
+
compressor,
|
|
230
|
+
decompressor
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
expect(manager.getSize()).toBe(8);
|
|
234
|
+
expect(manager.getBit(0)).toBe(true);
|
|
235
|
+
expect(manager.getBit(2)).toBe(true);
|
|
236
|
+
expect(manager.getBit(5)).toBe(true);
|
|
237
|
+
expect(manager.getBit(1)).toBe(false);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it("should handle empty set bits array", () => {
|
|
241
|
+
const manager = BitstringManager.fromSetBits(
|
|
242
|
+
8,
|
|
243
|
+
[],
|
|
244
|
+
compressor,
|
|
245
|
+
decompressor
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
expect(manager.getSize()).toBe(8);
|
|
249
|
+
expect(manager.getSetBits()).toEqual([]);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("should handle bits across byte boundaries", () => {
|
|
253
|
+
const manager = BitstringManager.fromSetBits(
|
|
254
|
+
16,
|
|
255
|
+
[7, 8, 15],
|
|
256
|
+
compressor,
|
|
257
|
+
decompressor
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
expect(manager.getBit(7)).toBe(true);
|
|
261
|
+
expect(manager.getBit(8)).toBe(true);
|
|
262
|
+
expect(manager.getBit(15)).toBe(true);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe("getRawBits", () => {
|
|
267
|
+
it("should return raw byte array", () => {
|
|
268
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
269
|
+
const raw = manager.getRawBits();
|
|
270
|
+
|
|
271
|
+
expect(raw).toBeInstanceOf(Uint8Array);
|
|
272
|
+
expect(raw.length).toBe(1); // 8 bits = 1 byte
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should return reference to internal bits array", () => {
|
|
276
|
+
const manager = new BitstringManager(8, compressor, decompressor);
|
|
277
|
+
const raw1 = manager.getRawBits();
|
|
278
|
+
manager.setBit(0, true);
|
|
279
|
+
const raw2 = manager.getRawBits();
|
|
280
|
+
|
|
281
|
+
// getRawBits returns a reference, so raw1 and raw2 are the same array
|
|
282
|
+
expect(raw1).toBe(raw2);
|
|
283
|
+
// Setting a bit should change the raw bits (same reference)
|
|
284
|
+
expect(raw1[0]).toBe(raw2[0]);
|
|
285
|
+
expect(raw1[0]).not.toBe(0); // Bit 0 is now set
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
describe("getSize", () => {
|
|
290
|
+
it("should return correct size", () => {
|
|
291
|
+
const manager = new BitstringManager(32, compressor, decompressor);
|
|
292
|
+
expect(manager.getSize()).toBe(32);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
describe("isIndexSet", () => {
|
|
298
|
+
let decompressor: DecompressionFunction;
|
|
299
|
+
|
|
300
|
+
beforeEach(() => {
|
|
301
|
+
decompressor = new MockDecompressor();
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("should return true for set bit", async () => {
|
|
305
|
+
const manager = new BitstringManager(8, new MockCompressor(), decompressor);
|
|
306
|
+
manager.setBit(3, true);
|
|
307
|
+
const encoded = await manager.encode();
|
|
308
|
+
|
|
309
|
+
const result = await isIndexSet(encoded, 3, decompressor);
|
|
310
|
+
expect(result).toBe(true);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("should return false for unset bit", async () => {
|
|
314
|
+
const manager = new BitstringManager(8, new MockCompressor(), decompressor);
|
|
315
|
+
manager.setBit(0, true);
|
|
316
|
+
manager.setBit(2, true);
|
|
317
|
+
const encoded = await manager.encode();
|
|
318
|
+
|
|
319
|
+
const result = await isIndexSet(encoded, 1, decompressor);
|
|
320
|
+
expect(result).toBe(false);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it("should return false for out of range index", async () => {
|
|
324
|
+
const manager = new BitstringManager(8, new MockCompressor(), decompressor);
|
|
325
|
+
const encoded = await manager.encode();
|
|
326
|
+
|
|
327
|
+
const result = await isIndexSet(encoded, 100, decompressor);
|
|
328
|
+
expect(result).toBe(false);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it("should handle multiple bits", async () => {
|
|
332
|
+
const manager = new BitstringManager(16, new MockCompressor(), decompressor);
|
|
333
|
+
manager.setBit(0, true);
|
|
334
|
+
manager.setBit(7, true);
|
|
335
|
+
manager.setBit(8, true);
|
|
336
|
+
manager.setBit(15, true);
|
|
337
|
+
const encoded = await manager.encode();
|
|
338
|
+
|
|
339
|
+
expect(await isIndexSet(encoded, 0, decompressor)).toBe(true);
|
|
340
|
+
expect(await isIndexSet(encoded, 7, decompressor)).toBe(true);
|
|
341
|
+
expect(await isIndexSet(encoded, 8, decompressor)).toBe(true);
|
|
342
|
+
expect(await isIndexSet(encoded, 15, decompressor)).toBe(true);
|
|
343
|
+
expect(await isIndexSet(encoded, 1, decompressor)).toBe(false);
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
|