@mania-labs/mania-sdk 1.0.0 → 1.0.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.
@@ -0,0 +1,357 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseEther } from 'viem';
3
+ import { BondingCurve, calculateBuyAmount, calculateSellAmount } from '../../bondingCurve.js';
4
+ import { CURVE_SCENARIOS, INITIAL_RESERVES } from '../helpers/fixtures.js';
5
+ import { TOTAL_FEE_BASIS_POINTS, MIGRATION_THRESHOLD } from '../../constants.js';
6
+
7
+ describe('BondingCurve', () => {
8
+ describe('constructor and getState', () => {
9
+ it('should create instance with provided state', () => {
10
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
11
+ const state = curve.getState();
12
+ expect(state.virtualTokenReserves).toBe(CURVE_SCENARIOS.FRESH.virtualTokenReserves);
13
+ });
14
+
15
+ it('should return a copy of state, not reference', () => {
16
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
17
+ const state1 = curve.getState();
18
+ const state2 = curve.getState();
19
+ expect(state1).toEqual(state2);
20
+ expect(state1).not.toBe(state2);
21
+ });
22
+ });
23
+
24
+ describe('isComplete', () => {
25
+ it('should return false for fresh curve', () => {
26
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
27
+ expect(curve.isComplete()).toBe(false);
28
+ });
29
+
30
+ it('should return true for complete curve', () => {
31
+ const curve = new BondingCurve(CURVE_SCENARIOS.COMPLETE, TOTAL_FEE_BASIS_POINTS);
32
+ expect(curve.isComplete()).toBe(true);
33
+ });
34
+ });
35
+
36
+ describe('isMigrated', () => {
37
+ it('should return false for active curve', () => {
38
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
39
+ expect(curve.isMigrated()).toBe(false);
40
+ });
41
+
42
+ it('should return false for complete but not migrated curve', () => {
43
+ const curve = new BondingCurve(CURVE_SCENARIOS.COMPLETE, TOTAL_FEE_BASIS_POINTS);
44
+ expect(curve.isMigrated()).toBe(false);
45
+ });
46
+
47
+ it('should return true for migrated curve (all reserves zero)', () => {
48
+ const curve = new BondingCurve(CURVE_SCENARIOS.MIGRATED, TOTAL_FEE_BASIS_POINTS);
49
+ expect(curve.isMigrated()).toBe(true);
50
+ });
51
+ });
52
+
53
+ describe('getCurrentPrice', () => {
54
+ it('should return price for fresh curve', () => {
55
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
56
+ const price = curve.getCurrentPrice();
57
+ expect(price).toBeGreaterThan(0n);
58
+ });
59
+
60
+ it('should return 0 for migrated curve', () => {
61
+ const curve = new BondingCurve(CURVE_SCENARIOS.MIGRATED, TOTAL_FEE_BASIS_POINTS);
62
+ expect(curve.getCurrentPrice()).toBe(0n);
63
+ });
64
+
65
+ it('should increase with more ETH reserves', () => {
66
+ const freshCurve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
67
+ const halfCurve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
68
+
69
+ expect(halfCurve.getCurrentPrice()).toBeGreaterThan(freshCurve.getCurrentPrice());
70
+ });
71
+ });
72
+
73
+ describe('getMarketCapEth', () => {
74
+ it('should calculate market cap correctly', () => {
75
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
76
+ const marketCap = curve.getMarketCapEth();
77
+ expect(marketCap).toBeGreaterThan(0n);
78
+ });
79
+
80
+ it('should return 0 for migrated curve', () => {
81
+ const curve = new BondingCurve(CURVE_SCENARIOS.MIGRATED, TOTAL_FEE_BASIS_POINTS);
82
+ expect(curve.getMarketCapEth()).toBe(0n);
83
+ });
84
+ });
85
+
86
+ describe('getMigrationProgress', () => {
87
+ it('should return 0 for fresh curve', () => {
88
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
89
+ expect(curve.getMigrationProgress()).toBe(0);
90
+ });
91
+
92
+ it('should return 50 for half-filled curve', () => {
93
+ const curve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
94
+ expect(curve.getMigrationProgress()).toBe(50);
95
+ });
96
+
97
+ it('should return 100 for complete curve', () => {
98
+ const curve = new BondingCurve(CURVE_SCENARIOS.COMPLETE, TOTAL_FEE_BASIS_POINTS);
99
+ expect(curve.getMigrationProgress()).toBe(100);
100
+ });
101
+ });
102
+
103
+ describe('getEthUntilMigration', () => {
104
+ it('should return 4 ETH for fresh curve', () => {
105
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
106
+ expect(curve.getEthUntilMigration()).toBe(MIGRATION_THRESHOLD);
107
+ });
108
+
109
+ it('should return 2 ETH for half-filled curve', () => {
110
+ const curve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
111
+ expect(curve.getEthUntilMigration()).toBe(parseEther('2'));
112
+ });
113
+
114
+ it('should return 0 for complete curve', () => {
115
+ const curve = new BondingCurve(CURVE_SCENARIOS.COMPLETE, TOTAL_FEE_BASIS_POINTS);
116
+ expect(curve.getEthUntilMigration()).toBe(0n);
117
+ });
118
+ });
119
+
120
+ describe('getBuyQuote', () => {
121
+ it('should return valid quote structure', () => {
122
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
123
+ const quote = curve.getBuyQuote(parseEther('0.1'));
124
+
125
+ expect(quote.tokensOut).toBeGreaterThan(0n);
126
+ expect(quote.fee).toBeGreaterThan(0n);
127
+ expect(quote.netEth).toBeGreaterThan(0n);
128
+ expect(quote.pricePerToken).toBeGreaterThan(0n);
129
+ });
130
+
131
+ it('should deduct fee from ETH amount', () => {
132
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
133
+ const ethAmount = parseEther('1');
134
+ const quote = curve.getBuyQuote(ethAmount);
135
+
136
+ expect(quote.fee).toBe(ethAmount / 100n); // 1% fee
137
+ expect(quote.netEth).toBe(ethAmount - quote.fee);
138
+ });
139
+
140
+ it('should return more tokens for larger ETH amounts', () => {
141
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
142
+ // Use smaller amounts that don't exceed realTokenReserves cap
143
+ const smallQuote = curve.getBuyQuote(parseEther('0.01'));
144
+ const largeQuote = curve.getBuyQuote(parseEther('0.02'));
145
+
146
+ expect(largeQuote.tokensOut).toBeGreaterThan(smallQuote.tokensOut);
147
+ });
148
+
149
+ it('should cap tokens at available supply', () => {
150
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
151
+ const hugeQuote = curve.getBuyQuote(parseEther('100'));
152
+
153
+ expect(hugeQuote.tokensOut).toBeLessThanOrEqual(CURVE_SCENARIOS.FRESH.realTokenReserves);
154
+ });
155
+ });
156
+
157
+ describe('getSellQuote', () => {
158
+ it('should return valid quote structure', () => {
159
+ const curve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
160
+ const quote = curve.getSellQuote(parseEther('1000000'));
161
+
162
+ expect(quote.ethOutGross).toBeGreaterThan(0n);
163
+ expect(quote.fee).toBeGreaterThan(0n);
164
+ expect(quote.ethOutNet).toBeGreaterThan(0n);
165
+ expect(quote.pricePerToken).toBeGreaterThan(0n);
166
+ });
167
+
168
+ it('should deduct fee from ETH output', () => {
169
+ const curve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
170
+ const quote = curve.getSellQuote(parseEther('1000000'));
171
+
172
+ expect(quote.ethOutNet).toBeLessThan(quote.ethOutGross);
173
+ expect(quote.ethOutNet).toBe(quote.ethOutGross - quote.fee);
174
+ });
175
+ });
176
+
177
+ describe('calculateMinTokensOut', () => {
178
+ it('should apply slippage correctly', () => {
179
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
180
+ const ethAmount = parseEther('0.1');
181
+ const quote = curve.getBuyQuote(ethAmount);
182
+ const minTokens = curve.calculateMinTokensOut(ethAmount, 100); // 1% slippage
183
+
184
+ expect(minTokens).toBeLessThan(quote.tokensOut);
185
+ // 1% slippage means 99% of quote
186
+ expect(minTokens).toBe((quote.tokensOut * 9900n) / 10000n);
187
+ });
188
+ });
189
+
190
+ describe('calculateMinEthOut', () => {
191
+ it('should apply slippage correctly', () => {
192
+ const curve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
193
+ const tokenAmount = parseEther('1000000');
194
+ const quote = curve.getSellQuote(tokenAmount);
195
+ const minEth = curve.calculateMinEthOut(tokenAmount, 100); // 1% slippage
196
+
197
+ expect(minEth).toBeLessThan(quote.ethOutNet);
198
+ // 1% slippage means 99% of quote
199
+ expect(minEth).toBe((quote.ethOutNet * 9900n) / 10000n);
200
+ });
201
+ });
202
+
203
+ describe('calculateBuyPriceImpact', () => {
204
+ it('should return positive impact for buys', () => {
205
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
206
+ const impact = curve.calculateBuyPriceImpact(parseEther('0.1'));
207
+ expect(impact).toBeGreaterThan(0);
208
+ });
209
+
210
+ it('should increase with larger buy amounts', () => {
211
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
212
+ const smallImpact = curve.calculateBuyPriceImpact(parseEther('0.01'));
213
+ const largeImpact = curve.calculateBuyPriceImpact(parseEther('1'));
214
+
215
+ expect(largeImpact).toBeGreaterThan(smallImpact);
216
+ });
217
+
218
+ it('should return 0 for zero price', () => {
219
+ const curve = new BondingCurve(CURVE_SCENARIOS.MIGRATED, TOTAL_FEE_BASIS_POINTS);
220
+ expect(curve.calculateBuyPriceImpact(parseEther('0.1'))).toBe(0);
221
+ });
222
+ });
223
+
224
+ describe('calculateSellPriceImpact', () => {
225
+ it('should return negative impact for sells', () => {
226
+ const curve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
227
+ const impact = curve.calculateSellPriceImpact(parseEther('1000000'));
228
+ expect(impact).toBeLessThan(0);
229
+ });
230
+
231
+ it('should return 0 for zero price', () => {
232
+ const curve = new BondingCurve(CURVE_SCENARIOS.MIGRATED, TOTAL_FEE_BASIS_POINTS);
233
+ expect(curve.calculateSellPriceImpact(parseEther('1000000'))).toBe(0);
234
+ });
235
+ });
236
+
237
+ describe('wouldExceedMigrationThreshold', () => {
238
+ it('should return false for small buys on fresh curve', () => {
239
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
240
+ expect(curve.wouldExceedMigrationThreshold(parseEther('0.1'))).toBe(false);
241
+ });
242
+
243
+ it('should return true for large buys on near-complete curve', () => {
244
+ const curve = new BondingCurve(CURVE_SCENARIOS.NEAR_COMPLETE, TOTAL_FEE_BASIS_POINTS);
245
+ expect(curve.wouldExceedMigrationThreshold(parseEther('0.5'))).toBe(true);
246
+ });
247
+ });
248
+
249
+ describe('getMaxBuyAmount', () => {
250
+ it('should return positive amount for fresh curve', () => {
251
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
252
+ const maxBuy = curve.getMaxBuyAmount();
253
+ expect(maxBuy).toBeGreaterThan(0n);
254
+ });
255
+
256
+ it('should return 0 for complete curve', () => {
257
+ const curve = new BondingCurve(CURVE_SCENARIOS.COMPLETE, TOTAL_FEE_BASIS_POINTS);
258
+ expect(curve.getMaxBuyAmount()).toBe(0n);
259
+ });
260
+
261
+ it('should account for fees', () => {
262
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
263
+ const maxBuy = curve.getMaxBuyAmount();
264
+ // Max buy should be slightly more than 4 ETH to account for fees
265
+ expect(maxBuy).toBeGreaterThan(MIGRATION_THRESHOLD);
266
+ });
267
+ });
268
+
269
+ describe('updateState', () => {
270
+ it('should update internal state', () => {
271
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
272
+ curve.updateState(CURVE_SCENARIOS.HALF_FILLED);
273
+
274
+ const state = curve.getState();
275
+ expect(state.realEthReserves).toBe(CURVE_SCENARIOS.HALF_FILLED.realEthReserves);
276
+ });
277
+ });
278
+
279
+ describe('fromContractData', () => {
280
+ it('should create instance from contract tuple', () => {
281
+ const data = [
282
+ INITIAL_RESERVES.virtualTokenReserves,
283
+ INITIAL_RESERVES.virtualEthReserves,
284
+ INITIAL_RESERVES.realTokenReserves,
285
+ 0n, // realEthReserves
286
+ INITIAL_RESERVES.tokenTotalSupply,
287
+ false, // complete
288
+ true, // trackVolume
289
+ ] as const;
290
+
291
+ const curve = BondingCurve.fromContractData(data, TOTAL_FEE_BASIS_POINTS);
292
+ const state = curve.getState();
293
+
294
+ expect(state.virtualTokenReserves).toBe(INITIAL_RESERVES.virtualTokenReserves);
295
+ expect(state.complete).toBe(false);
296
+ expect(state.trackVolume).toBe(true);
297
+ });
298
+ });
299
+ });
300
+
301
+ describe('calculateBuyAmount', () => {
302
+ it('should calculate tokens out correctly', () => {
303
+ const tokensOut = calculateBuyAmount(
304
+ INITIAL_RESERVES.virtualTokenReserves,
305
+ INITIAL_RESERVES.virtualEthReserves,
306
+ parseEther('0.1'),
307
+ TOTAL_FEE_BASIS_POINTS
308
+ );
309
+
310
+ expect(tokensOut).toBeGreaterThan(0n);
311
+ });
312
+
313
+ it('should match BondingCurve class calculation', () => {
314
+ const curve = new BondingCurve(CURVE_SCENARIOS.FRESH, TOTAL_FEE_BASIS_POINTS);
315
+ // Use smaller amount that doesn't trigger realTokenReserves cap
316
+ // (0.1 ETH would exceed cap, causing mismatch since utility can't cap)
317
+ const ethAmount = parseEther('0.01');
318
+
319
+ const classResult = curve.getBuyQuote(ethAmount).tokensOut;
320
+ const utilResult = calculateBuyAmount(
321
+ CURVE_SCENARIOS.FRESH.virtualTokenReserves,
322
+ CURVE_SCENARIOS.FRESH.virtualEthReserves,
323
+ ethAmount,
324
+ TOTAL_FEE_BASIS_POINTS
325
+ );
326
+
327
+ expect(utilResult).toBe(classResult);
328
+ });
329
+ });
330
+
331
+ describe('calculateSellAmount', () => {
332
+ it('should calculate ETH out correctly', () => {
333
+ const ethOut = calculateSellAmount(
334
+ CURVE_SCENARIOS.HALF_FILLED.virtualTokenReserves,
335
+ CURVE_SCENARIOS.HALF_FILLED.virtualEthReserves,
336
+ parseEther('1000000'),
337
+ TOTAL_FEE_BASIS_POINTS
338
+ );
339
+
340
+ expect(ethOut).toBeGreaterThan(0n);
341
+ });
342
+
343
+ it('should match BondingCurve class calculation', () => {
344
+ const curve = new BondingCurve(CURVE_SCENARIOS.HALF_FILLED, TOTAL_FEE_BASIS_POINTS);
345
+ const tokenAmount = parseEther('1000000');
346
+
347
+ const classResult = curve.getSellQuote(tokenAmount).ethOutNet;
348
+ const utilResult = calculateSellAmount(
349
+ CURVE_SCENARIOS.HALF_FILLED.virtualTokenReserves,
350
+ CURVE_SCENARIOS.HALF_FILLED.virtualEthReserves,
351
+ tokenAmount,
352
+ TOTAL_FEE_BASIS_POINTS
353
+ );
354
+
355
+ expect(utilResult).toBe(classResult);
356
+ });
357
+ });
@@ -0,0 +1,136 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseEther } from 'viem';
3
+ import {
4
+ PROTOCOL_FEE_BASIS_POINTS,
5
+ CREATOR_FEE_BASIS_POINTS,
6
+ TOTAL_FEE_BASIS_POINTS,
7
+ MAX_FEE_BASIS_POINTS,
8
+ MIGRATION_THRESHOLD,
9
+ TOKENS_FOR_LP,
10
+ MAX_MIGRATE_FEES,
11
+ UNISWAP_FEE_TIER,
12
+ TICK_LOWER,
13
+ TICK_UPPER,
14
+ DEFAULT_SLIPPAGE_BPS,
15
+ BPS_DENOMINATOR,
16
+ CHAIN_CONFIGS,
17
+ getChainConfig,
18
+ } from '../../constants.js';
19
+
20
+ describe('Fee Constants', () => {
21
+ it('should have correct protocol fee (0.70%)', () => {
22
+ expect(PROTOCOL_FEE_BASIS_POINTS).toBe(70n);
23
+ });
24
+
25
+ it('should have correct creator fee (0.30%)', () => {
26
+ expect(CREATOR_FEE_BASIS_POINTS).toBe(30n);
27
+ });
28
+
29
+ it('should have correct total fee (1.00%)', () => {
30
+ expect(TOTAL_FEE_BASIS_POINTS).toBe(100n);
31
+ });
32
+
33
+ it('should have fees sum correctly', () => {
34
+ expect(PROTOCOL_FEE_BASIS_POINTS + CREATOR_FEE_BASIS_POINTS).toBe(TOTAL_FEE_BASIS_POINTS);
35
+ });
36
+
37
+ it('should have max fee of 10%', () => {
38
+ expect(MAX_FEE_BASIS_POINTS).toBe(1000n);
39
+ });
40
+ });
41
+
42
+ describe('Migration Constants', () => {
43
+ it('should have migration threshold of 4 ETH', () => {
44
+ expect(MIGRATION_THRESHOLD).toBe(parseEther('4'));
45
+ });
46
+
47
+ it('should have tokens for LP of 206.9M', () => {
48
+ expect(TOKENS_FOR_LP).toBe(206_900_000_000_000_000_000_000_000n);
49
+ });
50
+
51
+ it('should have max migrate fees of 0.0003 ETH', () => {
52
+ expect(MAX_MIGRATE_FEES).toBe(300_000_000_000_000n);
53
+ });
54
+ });
55
+
56
+ describe('Uniswap V3 Constants', () => {
57
+ it('should have fee tier of 0.3%', () => {
58
+ expect(UNISWAP_FEE_TIER).toBe(3000);
59
+ });
60
+
61
+ it('should have full range tick lower', () => {
62
+ expect(TICK_LOWER).toBe(-887220);
63
+ });
64
+
65
+ it('should have full range tick upper', () => {
66
+ expect(TICK_UPPER).toBe(887220);
67
+ });
68
+
69
+ it('should have symmetric tick range', () => {
70
+ expect(Math.abs(TICK_LOWER)).toBe(TICK_UPPER);
71
+ });
72
+ });
73
+
74
+ describe('Default Slippage', () => {
75
+ it('should have default slippage of 1%', () => {
76
+ expect(DEFAULT_SLIPPAGE_BPS).toBe(100);
77
+ });
78
+ });
79
+
80
+ describe('BPS Denominator', () => {
81
+ it('should be 10000', () => {
82
+ expect(BPS_DENOMINATOR).toBe(10000n);
83
+ });
84
+ });
85
+
86
+ describe('Chain Configurations', () => {
87
+ it('should have Mega ETH Testnet config', () => {
88
+ const config = CHAIN_CONFIGS[6343];
89
+ expect(config).toBeDefined();
90
+ expect(config.chainId).toBe(6343);
91
+ expect(config.name).toBe('Mega Eth Testnet');
92
+ });
93
+
94
+ it('should have valid factory address', () => {
95
+ const config = CHAIN_CONFIGS[6343];
96
+ expect(config.factoryAddress).toMatch(/^0x[a-fA-F0-9]{40}$/);
97
+ });
98
+
99
+ it('should have valid WETH address', () => {
100
+ const config = CHAIN_CONFIGS[6343];
101
+ expect(config.wethAddress).toMatch(/^0x[a-fA-F0-9]{40}$/);
102
+ });
103
+
104
+ it('should have valid position manager address', () => {
105
+ const config = CHAIN_CONFIGS[6343];
106
+ expect(config.nonfungiblePositionManager).toMatch(/^0x[a-fA-F0-9]{40}$/);
107
+ });
108
+
109
+ it('should have valid Uniswap factory address', () => {
110
+ const config = CHAIN_CONFIGS[6343];
111
+ expect(config.uniswapV3Factory).toMatch(/^0x[a-fA-F0-9]{40}$/);
112
+ });
113
+
114
+ it('should have block explorer URL', () => {
115
+ const config = CHAIN_CONFIGS[6343];
116
+ expect(config.blockExplorer).toMatch(/^https?:\/\//);
117
+ });
118
+ });
119
+
120
+ describe('getChainConfig', () => {
121
+ it('should return config for supported chain', () => {
122
+ const config = getChainConfig(6343);
123
+ expect(config).toBeDefined();
124
+ expect(config?.chainId).toBe(6343);
125
+ });
126
+
127
+ it('should return undefined for unsupported chain', () => {
128
+ const config = getChainConfig(99999);
129
+ expect(config).toBeUndefined();
130
+ });
131
+
132
+ it('should return undefined for invalid chain ID', () => {
133
+ const config = getChainConfig(0);
134
+ expect(config).toBeUndefined();
135
+ });
136
+ });