@holoscript/std 7.0.0 → 7.0.1
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/README.md +8 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/{chunk-PFX2JM4X.js → chunk-FAMOLKH3.js} +2 -1
- package/dist/{chunk-PFX2JM4X.js.map → chunk-FAMOLKH3.js.map} +1 -1
- package/dist/{chunk-DZHAVOCH.js → chunk-SOKH6FJ7.js} +31 -6
- package/dist/chunk-SOKH6FJ7.js.map +1 -0
- package/dist/collections.cjs +1 -0
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +2 -2
- package/dist/fs/fs.d.ts.map +1 -1
- package/dist/fs/index.cjs +221 -8510
- package/dist/fs/index.cjs.map +1 -1
- package/dist/fs/index.js +832 -118
- package/dist/fs/index.js.map +1 -1
- package/dist/fs/sandbox.d.ts +49 -0
- package/dist/fs/sandbox.d.ts.map +1 -0
- package/dist/index.cjs +3494 -12672
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/math.cjs +18 -3
- package/dist/math.cjs.map +1 -1
- package/dist/math.js +2 -2
- package/dist/string.js +1 -1
- package/dist/time.js +1 -1
- package/dist/traits/EconomicPrimitives.js +1 -1
- package/dist/traits/EconomicTraits.js +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -9
- package/dist/__tests__/EconomicPrimitives.test.d.ts +0 -2
- package/dist/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
- package/dist/__tests__/EconomicTraits.test.d.ts +0 -2
- package/dist/__tests__/EconomicTraits.test.d.ts.map +0 -1
- package/dist/__tests__/SimulationLabPrimitives.test.d.ts +0 -2
- package/dist/__tests__/SimulationLabPrimitives.test.d.ts.map +0 -1
- package/dist/__tests__/collections.test.d.ts +0 -2
- package/dist/__tests__/collections.test.d.ts.map +0 -1
- package/dist/__tests__/events.test.d.ts +0 -2
- package/dist/__tests__/events.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/materials.test.d.ts +0 -2
- package/dist/__tests__/materials.test.d.ts.map +0 -1
- package/dist/__tests__/math.test.d.ts +0 -2
- package/dist/__tests__/math.test.d.ts.map +0 -1
- package/dist/__tests__/physics.test.d.ts +0 -2
- package/dist/__tests__/physics.test.d.ts.map +0 -1
- package/dist/__tests__/spatial.test.d.ts +0 -2
- package/dist/__tests__/spatial.test.d.ts.map +0 -1
- package/dist/__tests__/standard-library-fundamentals.test.d.ts +0 -2
- package/dist/__tests__/standard-library-fundamentals.test.d.ts.map +0 -1
- package/dist/__tests__/string-and-time-utilities.test.d.ts +0 -2
- package/dist/__tests__/string-and-time-utilities.test.d.ts.map +0 -1
- package/dist/__tests__/string-decoupled.test.d.ts +0 -2
- package/dist/__tests__/string-decoupled.test.d.ts.map +0 -1
- package/dist/__tests__/string.test.d.ts +0 -2
- package/dist/__tests__/string.test.d.ts.map +0 -1
- package/dist/__tests__/time.test.d.ts +0 -2
- package/dist/__tests__/time.test.d.ts.map +0 -1
- package/dist/chunk-DZHAVOCH.js.map +0 -1
- package/dist/chunk-PR4QN5HX.js +0 -43
- package/dist/chunk-XBA4ARST.js +0 -9313
- package/dist/chunk-XBA4ARST.js.map +0 -1
- package/dist/fs/__tests__/file-watch-system.test.d.ts +0 -2
- package/dist/fs/__tests__/file-watch-system.test.d.ts.map +0 -1
- package/dist/fs/__tests__/path-utilities.test.d.ts +0 -2
- package/dist/fs/__tests__/path-utilities.test.d.ts.map +0 -1
- package/dist/fs/__tests__/path.test.d.ts +0 -2
- package/dist/fs/__tests__/path.test.d.ts.map +0 -1
- package/dist/string.basic.test.d.ts +0 -5
- package/dist/string.basic.test.d.ts.map +0 -1
- package/dist/string.test.d.ts +0 -5
- package/dist/string.test.d.ts.map +0 -1
- package/dist/traits/__tests__/ARTraits.test.d.ts +0 -2
- package/dist/traits/__tests__/ARTraits.test.d.ts.map +0 -1
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts +0 -2
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
- package/dist/traits/__tests__/EconomicTraits.test.d.ts +0 -2
- package/dist/traits/__tests__/EconomicTraits.test.d.ts.map +0 -1
- package/error-utf8.log +0 -6
- package/error.log +0 -0
- package/src/__tests__/EconomicPrimitives.test.ts +0 -690
- package/src/__tests__/EconomicTraits.test.ts +0 -425
- package/src/__tests__/SimulationLabPrimitives.test.ts +0 -415
- package/src/__tests__/collections.test.ts +0 -182
- package/src/__tests__/events.test.ts +0 -135
- package/src/__tests__/index.test.ts +0 -14
- package/src/__tests__/materials.test.ts +0 -84
- package/src/__tests__/math.test.ts +0 -246
- package/src/__tests__/physics.test.ts +0 -83
- package/src/__tests__/spatial.test.ts +0 -333
- package/src/__tests__/standard-library-fundamentals.test.ts +0 -1318
- package/src/__tests__/string-and-time-utilities.test.ts +0 -1070
- package/src/__tests__/string-decoupled.test.ts +0 -13
- package/src/__tests__/string.test.ts +0 -164
- package/src/__tests__/time.test.ts +0 -110
- package/src/collections.ts +0 -850
- package/src/events.ts +0 -88
- package/src/fs/__tests__/file-watch-system.test.ts +0 -675
- package/src/fs/__tests__/path-utilities.test.ts +0 -375
- package/src/fs/__tests__/path.test.ts +0 -287
- package/src/fs/fs.ts +0 -692
- package/src/fs/index.ts +0 -194
- package/src/fs/path.ts +0 -310
- package/src/fs/watch.ts +0 -413
- package/src/index.ts +0 -476
- package/src/materials.ts +0 -109
- package/src/math.ts +0 -674
- package/src/physics.ts +0 -141
- package/src/spatial.ts +0 -320
- package/src/string.basic.test.ts +0 -14
- package/src/string.test.ts +0 -335
- package/src/string.ts +0 -531
- package/src/time.ts +0 -621
- package/src/traits/ARTraits.ts +0 -103
- package/src/traits/EconomicPrimitives.ts +0 -755
- package/src/traits/EconomicTraits.ts +0 -552
- package/src/traits/IoTTraits.ts +0 -102
- package/src/traits/SimulationLabPrimitives.ts +0 -650
- package/src/traits/SimulationLabTraits.ts +0 -191
- package/src/traits/VRRTraits.ts +0 -326
- package/src/traits/__tests__/ARTraits.test.ts +0 -8
- package/src/traits/__tests__/EconomicPrimitives.test.ts +0 -14
- package/src/traits/__tests__/EconomicTraits.test.ts +0 -16
- package/src/types.ts +0 -418
- package/std_error.log +0 -5
- package/tsconfig.json +0 -18
- package/tsup.config.ts +0 -20
- package/vitest.config.ts +0 -10
- /package/dist/{chunk-PR4QN5HX.js.map → chunk-DGUM43GV.js.map} +0 -0
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
EconomicTraits,
|
|
4
|
-
getEconomicTraitNames,
|
|
5
|
-
getEconomicTrait,
|
|
6
|
-
validateTraitComposition,
|
|
7
|
-
getRequiredPermissions,
|
|
8
|
-
} from '../traits/EconomicTraits.js';
|
|
9
|
-
import type { EconomicTraitDefinition } from '../traits/EconomicTraits.js';
|
|
10
|
-
|
|
11
|
-
// =============================================================================
|
|
12
|
-
// TRAIT DEFINITION STRUCTURE
|
|
13
|
-
// =============================================================================
|
|
14
|
-
|
|
15
|
-
describe('EconomicTraits', () => {
|
|
16
|
-
it('should define exactly five economic traits', () => {
|
|
17
|
-
expect(Object.keys(EconomicTraits)).toHaveLength(5);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should include all five trait names', () => {
|
|
21
|
-
const keys = Object.keys(EconomicTraits);
|
|
22
|
-
expect(keys).toContain('tradeable');
|
|
23
|
-
expect(keys).toContain('depreciating');
|
|
24
|
-
expect(keys).toContain('bonding_curved');
|
|
25
|
-
expect(keys).toContain('taxable_wealth');
|
|
26
|
-
expect(keys).toContain('pid_controlled');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should prefix all trait names with @', () => {
|
|
30
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
31
|
-
expect(trait.name).toMatch(/^@/);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('should have descriptions for all traits', () => {
|
|
36
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
37
|
-
expect(trait.description).toBeDefined();
|
|
38
|
-
expect(typeof trait.description).toBe('string');
|
|
39
|
-
expect(trait.description!.length).toBeGreaterThan(10);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should have validators for all traits', () => {
|
|
44
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
45
|
-
expect(trait.validator).toBeDefined();
|
|
46
|
-
expect(typeof trait.validator).toBe('function');
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should have requiredPermissions for all traits', () => {
|
|
51
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
52
|
-
expect(trait.requiredPermissions).toBeDefined();
|
|
53
|
-
expect(trait.requiredPermissions.length).toBeGreaterThan(0);
|
|
54
|
-
for (const perm of trait.requiredPermissions) {
|
|
55
|
-
expect(perm).toMatch(/^economy\./);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should have economicLayer for all traits', () => {
|
|
61
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
62
|
-
expect(typeof trait.economicLayer).toBe('number');
|
|
63
|
-
expect(trait.economicLayer).toBeGreaterThanOrEqual(0);
|
|
64
|
-
expect(trait.economicLayer).toBeLessThanOrEqual(8);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should have composesWith for all traits', () => {
|
|
69
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
70
|
-
expect(trait.composesWith).toBeDefined();
|
|
71
|
-
expect(Array.isArray(trait.composesWith)).toBe(true);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should have compiler_hints for all traits', () => {
|
|
76
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
77
|
-
expect(trait.compiler_hints).toBeDefined();
|
|
78
|
-
expect(trait.compiler_hints!.requires_runtime).toBeDefined();
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// =============================================================================
|
|
84
|
-
// INDIVIDUAL TRAIT VALIDATORS
|
|
85
|
-
// =============================================================================
|
|
86
|
-
|
|
87
|
-
describe('@tradeable validator', () => {
|
|
88
|
-
const validator = EconomicTraits.tradeable.validator!;
|
|
89
|
-
|
|
90
|
-
it('should accept valid params with required initial_owner', () => {
|
|
91
|
-
expect(validator({ initial_owner: 'player-1' })).toBe(true);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should reject missing initial_owner', () => {
|
|
95
|
-
expect(validator({})).toBe(false);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should reject non-string initial_owner', () => {
|
|
99
|
-
expect(validator({ initial_owner: 123 })).toBe(false);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should reject negative min_price', () => {
|
|
103
|
-
expect(validator({ initial_owner: 'player-1', min_price: -10 })).toBe(false);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should accept zero min_price', () => {
|
|
107
|
-
expect(validator({ initial_owner: 'player-1', min_price: 0 })).toBe(true);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('@depreciating validator', () => {
|
|
112
|
-
const validator = EconomicTraits.depreciating.validator!;
|
|
113
|
-
|
|
114
|
-
it('should accept valid decay_rate', () => {
|
|
115
|
-
expect(validator({ decay_rate: 0.001 })).toBe(true);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('should reject missing decay_rate', () => {
|
|
119
|
-
expect(validator({})).toBe(false);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should reject negative decay_rate', () => {
|
|
123
|
-
expect(validator({ decay_rate: -0.01 })).toBe(false);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should reject decay_rate > 1', () => {
|
|
127
|
-
expect(validator({ decay_rate: 1.5 })).toBe(false);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should accept decay_rate = 0 (no depreciation)', () => {
|
|
131
|
-
expect(validator({ decay_rate: 0 })).toBe(true);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should reject invalid initial_condition', () => {
|
|
135
|
-
expect(validator({ decay_rate: 0.001, initial_condition: 1.5 })).toBe(false);
|
|
136
|
-
expect(validator({ decay_rate: 0.001, initial_condition: -0.1 })).toBe(false);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should reject invalid destroy_threshold', () => {
|
|
140
|
-
expect(validator({ decay_rate: 0.001, destroy_threshold: 1.5 })).toBe(false);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe('@bonding_curved validator', () => {
|
|
145
|
-
const validator = EconomicTraits.bonding_curved.validator!;
|
|
146
|
-
|
|
147
|
-
it('should accept valid reserve_ratio', () => {
|
|
148
|
-
expect(validator({ reserve_ratio: 1.0 })).toBe(true);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('should reject missing reserve_ratio', () => {
|
|
152
|
-
expect(validator({})).toBe(false);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('should reject zero reserve_ratio', () => {
|
|
156
|
-
expect(validator({ reserve_ratio: 0 })).toBe(false);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should reject negative reserve_ratio', () => {
|
|
160
|
-
expect(validator({ reserve_ratio: -1 })).toBe(false);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('should reject invalid curve_type', () => {
|
|
164
|
-
expect(validator({ reserve_ratio: 1.0, curve_type: 'quadratic' })).toBe(false);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should accept valid curve_type values', () => {
|
|
168
|
-
expect(validator({ reserve_ratio: 1.0, curve_type: 'linear' })).toBe(true);
|
|
169
|
-
expect(validator({ reserve_ratio: 1.0, curve_type: 'exponential' })).toBe(true);
|
|
170
|
-
expect(validator({ reserve_ratio: 1.0, curve_type: 'logarithmic' })).toBe(true);
|
|
171
|
-
expect(validator({ reserve_ratio: 1.0, curve_type: 'sigmoid' })).toBe(true);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it('should reject transaction_fee > 0.5', () => {
|
|
175
|
-
expect(validator({ reserve_ratio: 1.0, transaction_fee: 0.6 })).toBe(false);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it('should reject negative transaction_fee', () => {
|
|
179
|
-
expect(validator({ reserve_ratio: 1.0, transaction_fee: -0.01 })).toBe(false);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it('should reject zero curve_steepness', () => {
|
|
183
|
-
expect(validator({ reserve_ratio: 1.0, curve_steepness: 0 })).toBe(false);
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
describe('@taxable_wealth validator', () => {
|
|
188
|
-
const validator = EconomicTraits.taxable_wealth.validator!;
|
|
189
|
-
|
|
190
|
-
it('should accept valid threshold', () => {
|
|
191
|
-
expect(validator({ threshold: 10000 })).toBe(true);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('should reject missing threshold', () => {
|
|
195
|
-
expect(validator({})).toBe(false);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('should reject negative threshold', () => {
|
|
199
|
-
expect(validator({ threshold: -100 })).toBe(false);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('should accept zero threshold (everyone taxed)', () => {
|
|
203
|
-
expect(validator({ threshold: 0 })).toBe(true);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it('should reject base_rate > 0.1', () => {
|
|
207
|
-
expect(validator({ threshold: 10000, base_rate: 0.2 })).toBe(false);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
it('should reject redistribution_fraction > 1.0', () => {
|
|
211
|
-
expect(validator({ threshold: 10000, redistribution_fraction: 1.5 })).toBe(false);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('should reject max_effective_rate > 1.0', () => {
|
|
215
|
-
expect(validator({ threshold: 10000, max_effective_rate: 1.5 })).toBe(false);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe('@pid_controlled validator', () => {
|
|
220
|
-
const validator = EconomicTraits.pid_controlled.validator!;
|
|
221
|
-
|
|
222
|
-
it('should accept valid target_per_capita', () => {
|
|
223
|
-
expect(validator({ target_per_capita: 1000 })).toBe(true);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('should reject missing target_per_capita', () => {
|
|
227
|
-
expect(validator({})).toBe(false);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it('should reject zero target_per_capita', () => {
|
|
231
|
-
expect(validator({ target_per_capita: 0 })).toBe(false);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it('should reject negative target_per_capita', () => {
|
|
235
|
-
expect(validator({ target_per_capita: -100 })).toBe(false);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it('should reject NaN PID gains', () => {
|
|
239
|
-
expect(validator({ target_per_capita: 1000, inner_kp: NaN })).toBe(false);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should accept negative PID gains (valid control theory)', () => {
|
|
243
|
-
expect(validator({ target_per_capita: 1000, inner_kp: -0.5 })).toBe(true);
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it('should reject zero update_interval', () => {
|
|
247
|
-
expect(validator({ target_per_capita: 1000, update_interval: 0 })).toBe(false);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
it('should reject negative update_interval', () => {
|
|
251
|
-
expect(validator({ target_per_capita: 1000, update_interval: -1 })).toBe(false);
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// =============================================================================
|
|
256
|
-
// UTILITY FUNCTIONS
|
|
257
|
-
// =============================================================================
|
|
258
|
-
|
|
259
|
-
describe('getEconomicTraitNames', () => {
|
|
260
|
-
it('should return all five trait names', () => {
|
|
261
|
-
const names = getEconomicTraitNames();
|
|
262
|
-
expect(names).toHaveLength(5);
|
|
263
|
-
expect(names).toContain('@tradeable');
|
|
264
|
-
expect(names).toContain('@depreciating');
|
|
265
|
-
expect(names).toContain('@bonding_curved');
|
|
266
|
-
expect(names).toContain('@taxable_wealth');
|
|
267
|
-
expect(names).toContain('@pid_controlled');
|
|
268
|
-
});
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
describe('getEconomicTrait', () => {
|
|
272
|
-
it('should find trait by @-prefixed name', () => {
|
|
273
|
-
const trait = getEconomicTrait('@tradeable');
|
|
274
|
-
expect(trait).toBeDefined();
|
|
275
|
-
expect(trait!.name).toBe('@tradeable');
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
it('should find trait by unprefixed name', () => {
|
|
279
|
-
const trait = getEconomicTrait('tradeable');
|
|
280
|
-
expect(trait).toBeDefined();
|
|
281
|
-
expect(trait!.name).toBe('@tradeable');
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it('should return undefined for unknown trait', () => {
|
|
285
|
-
const trait = getEconomicTrait('@unknown');
|
|
286
|
-
expect(trait).toBeUndefined();
|
|
287
|
-
});
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
describe('validateTraitComposition', () => {
|
|
291
|
-
it('should accept compatible traits', () => {
|
|
292
|
-
const result = validateTraitComposition(['@tradeable', '@depreciating']);
|
|
293
|
-
expect(result).toBeNull();
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
it('should reject unknown traits', () => {
|
|
297
|
-
const result = validateTraitComposition(['@tradeable', '@unknown']);
|
|
298
|
-
expect(result).not.toBeNull();
|
|
299
|
-
expect(result).toContain('Unknown');
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it('should accept single trait', () => {
|
|
303
|
-
const result = validateTraitComposition(['@tradeable']);
|
|
304
|
-
expect(result).toBeNull();
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
it('should accept tradeable + bonding_curved composition', () => {
|
|
308
|
-
const result = validateTraitComposition(['@tradeable', '@bonding_curved']);
|
|
309
|
-
expect(result).toBeNull();
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it('should accept tradeable + taxable_wealth composition', () => {
|
|
313
|
-
const result = validateTraitComposition(['@tradeable', '@taxable_wealth']);
|
|
314
|
-
expect(result).toBeNull();
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it('should accept bonding_curved + pid_controlled composition', () => {
|
|
318
|
-
const result = validateTraitComposition(['@bonding_curved', '@pid_controlled']);
|
|
319
|
-
expect(result).toBeNull();
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it('should reject incompatible compositions', () => {
|
|
323
|
-
// depreciating does not compose with pid_controlled (and vice versa)
|
|
324
|
-
const result = validateTraitComposition(['@depreciating', '@pid_controlled']);
|
|
325
|
-
expect(result).not.toBeNull();
|
|
326
|
-
expect(result).toContain('does not compose');
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
describe('getRequiredPermissions', () => {
|
|
331
|
-
it('should return unique sorted permissions', () => {
|
|
332
|
-
const perms = getRequiredPermissions(['@tradeable', '@taxable_wealth']);
|
|
333
|
-
expect(perms).toContain('economy.trade');
|
|
334
|
-
expect(perms).toContain('economy.tax');
|
|
335
|
-
expect(perms).toContain('economy.redistribute');
|
|
336
|
-
// Should be sorted
|
|
337
|
-
for (let i = 1; i < perms.length; i++) {
|
|
338
|
-
expect(perms[i] >= perms[i - 1]).toBe(true);
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
it('should return empty for no traits', () => {
|
|
343
|
-
expect(getRequiredPermissions([])).toHaveLength(0);
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
it('should return empty for unknown traits', () => {
|
|
347
|
-
expect(getRequiredPermissions(['@unknown'])).toHaveLength(0);
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
it('should deduplicate shared permissions', () => {
|
|
351
|
-
// Both tradeable and bonding_curved require economy.trade
|
|
352
|
-
const perms = getRequiredPermissions(['@tradeable', '@bonding_curved']);
|
|
353
|
-
const tradeCount = perms.filter((p) => p === 'economy.trade').length;
|
|
354
|
-
expect(tradeCount).toBe(1);
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
it('should aggregate all permissions for full economic stack', () => {
|
|
358
|
-
const perms = getRequiredPermissions([
|
|
359
|
-
'@tradeable',
|
|
360
|
-
'@depreciating',
|
|
361
|
-
'@bonding_curved',
|
|
362
|
-
'@taxable_wealth',
|
|
363
|
-
'@pid_controlled',
|
|
364
|
-
]);
|
|
365
|
-
expect(perms).toContain('economy.trade');
|
|
366
|
-
expect(perms).toContain('economy.burn');
|
|
367
|
-
expect(perms).toContain('economy.set_price');
|
|
368
|
-
expect(perms).toContain('economy.tax');
|
|
369
|
-
expect(perms).toContain('economy.redistribute');
|
|
370
|
-
expect(perms).toContain('economy.tune_pid');
|
|
371
|
-
expect(perms).toContain('economy.mint');
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
// =============================================================================
|
|
376
|
-
// RBAC INTEGRATION
|
|
377
|
-
// =============================================================================
|
|
378
|
-
|
|
379
|
-
describe('RBAC Integration', () => {
|
|
380
|
-
it('should use economy.* permission namespace', () => {
|
|
381
|
-
const allPerms = new Set<string>();
|
|
382
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
383
|
-
for (const perm of trait.requiredPermissions) {
|
|
384
|
-
allPerms.add(perm);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
for (const perm of allPerms) {
|
|
388
|
-
expect(perm.startsWith('economy.')).toBe(true);
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
it('should not require wildcard permissions on individual traits', () => {
|
|
393
|
-
for (const trait of Object.values(EconomicTraits)) {
|
|
394
|
-
for (const perm of trait.requiredPermissions) {
|
|
395
|
-
expect(perm).not.toBe('economy.*');
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
// =============================================================================
|
|
402
|
-
// ECONOMIC LAYER ARCHITECTURE
|
|
403
|
-
// =============================================================================
|
|
404
|
-
|
|
405
|
-
describe('9-Layer Architecture Mapping', () => {
|
|
406
|
-
it('@tradeable should be at Layer 0 (Integrity)', () => {
|
|
407
|
-
expect(EconomicTraits.tradeable.economicLayer).toBe(0);
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
it('@depreciating should be at Layer 1 (Flow Control)', () => {
|
|
411
|
-
expect(EconomicTraits.depreciating.economicLayer).toBe(1);
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
it('@bonding_curved should be at Layer 2 (Price Discovery)', () => {
|
|
415
|
-
expect(EconomicTraits.bonding_curved.economicLayer).toBe(2);
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
it('@taxable_wealth should be at Layer 4 (Redistribution)', () => {
|
|
419
|
-
expect(EconomicTraits.taxable_wealth.economicLayer).toBe(4);
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
it('@pid_controlled should be at Layer 1 (Flow Control)', () => {
|
|
423
|
-
expect(EconomicTraits.pid_controlled.economicLayer).toBe(1);
|
|
424
|
-
});
|
|
425
|
-
});
|