smiles-js 2.0.3 → 2.2.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/API.md +162 -0
- package/README.md +39 -0
- package/docs/MIRROR_PLAN.md +204 -0
- package/docs/smiles.peggy +215 -0
- package/package.json +1 -1
- package/scripts/coverage-summary.js +1 -1
- package/src/codegen/branch-crossing-ring.js +27 -6
- package/src/codegen/interleaved-fused-ring.js +24 -0
- package/src/decompiler.js +236 -51
- package/src/decompiler.test.js +232 -60
- package/src/fragment.test.js +7 -2
- package/src/manipulation.js +409 -4
- package/src/manipulation.test.js +359 -1
- package/src/method-attachers.js +37 -8
- package/src/node-creators.js +7 -0
- package/src/parser/ast-builder.js +23 -8
- package/src/parser/ring-group-builder.js +14 -2
- package/src/parser/ring-utils.js +28 -0
- package/test-integration/__snapshots__/acetaminophen.test.js.snap +20 -0
- package/test-integration/__snapshots__/adjuvant-analgesics.test.js.snap +63 -1
- package/test-integration/__snapshots__/cholesterol-drugs.test.js.snap +437 -0
- package/test-integration/__snapshots__/dexamethasone.test.js.snap +31 -0
- package/test-integration/__snapshots__/endocannabinoids.test.js.snap +79 -2
- package/test-integration/__snapshots__/endogenous-opioids.test.js.snap +1116 -0
- package/test-integration/__snapshots__/hypertension-medication.test.js.snap +70 -1
- package/test-integration/__snapshots__/local-anesthetics.test.js.snap +97 -0
- package/test-integration/__snapshots__/nsaids-otc.test.js.snap +61 -1
- package/test-integration/__snapshots__/nsaids-prescription.test.js.snap +115 -2
- package/test-integration/__snapshots__/opioids.test.js.snap +113 -4
- package/test-integration/__snapshots__/steroids.test.js.snap +381 -2
- package/test-integration/acetaminophen.test.js +15 -3
- package/test-integration/adjuvant-analgesics.test.js +43 -7
- package/test-integration/cholesterol-drugs.test.js +127 -20
- package/test-integration/cholesterol.test.js +112 -0
- package/test-integration/dexamethasone.test.js +8 -2
- package/test-integration/endocannabinoids.test.js +48 -12
- package/test-integration/endogenous-opioids.smiles.js +32 -0
- package/test-integration/endogenous-opioids.test.js +192 -0
- package/test-integration/hypertension-medication.test.js +32 -8
- package/test-integration/local-anesthetics.smiles.js +33 -0
- package/test-integration/local-anesthetics.test.js +64 -16
- package/test-integration/mirror.test.js +151 -0
- package/test-integration/nsaids-otc.test.js +40 -10
- package/test-integration/nsaids-prescription.test.js +72 -18
- package/test-integration/opioids.test.js +56 -14
- package/test-integration/polymer.test.js +148 -0
- package/test-integration/steroids.test.js +112 -28
- package/test-integration/utils.js +4 -2
- package/todo +2 -3
|
@@ -39,6 +39,12 @@ describe('Cortisone Integration Test', () => {
|
|
|
39
39
|
expect(code).toMatchSnapshot();
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
+
test('generates valid verbose code via toCode()', () => {
|
|
43
|
+
const ast = parse(CORTISONE_SMILES);
|
|
44
|
+
const code = ast.toCode('v', { verbose: true });
|
|
45
|
+
expect(code).toMatchSnapshot();
|
|
46
|
+
});
|
|
47
|
+
|
|
42
48
|
test('generated code is valid JavaScript', () => {
|
|
43
49
|
const ast = parse(CORTISONE_SMILES);
|
|
44
50
|
const code = ast.toCode('v');
|
|
@@ -46,14 +52,14 @@ describe('Cortisone Integration Test', () => {
|
|
|
46
52
|
|
|
47
53
|
let factory;
|
|
48
54
|
expect(() => {
|
|
49
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
55
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
50
56
|
}).not.toThrow();
|
|
51
57
|
expect(typeof factory).toBe('function');
|
|
52
58
|
});
|
|
53
59
|
|
|
54
60
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
55
61
|
const ast = parse(CORTISONE_SMILES);
|
|
56
|
-
const code = ast.toCode('v');
|
|
62
|
+
const code = ast.toCode('v', { verbose: true });
|
|
57
63
|
const executableCode = stripExports(code);
|
|
58
64
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
59
65
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -80,6 +86,12 @@ describe('Hydrocortisone Integration Test', () => {
|
|
|
80
86
|
expect(code).toMatchSnapshot();
|
|
81
87
|
});
|
|
82
88
|
|
|
89
|
+
test('generates valid verbose code via toCode()', () => {
|
|
90
|
+
const ast = parse(HYDROCORTISONE_SMILES);
|
|
91
|
+
const code = ast.toCode('v', { verbose: true });
|
|
92
|
+
expect(code).toMatchSnapshot();
|
|
93
|
+
});
|
|
94
|
+
|
|
83
95
|
test('generated code is valid JavaScript', () => {
|
|
84
96
|
const ast = parse(HYDROCORTISONE_SMILES);
|
|
85
97
|
const code = ast.toCode('v');
|
|
@@ -87,14 +99,14 @@ describe('Hydrocortisone Integration Test', () => {
|
|
|
87
99
|
|
|
88
100
|
let factory;
|
|
89
101
|
expect(() => {
|
|
90
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
102
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
91
103
|
}).not.toThrow();
|
|
92
104
|
expect(typeof factory).toBe('function');
|
|
93
105
|
});
|
|
94
106
|
|
|
95
107
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
96
108
|
const ast = parse(HYDROCORTISONE_SMILES);
|
|
97
|
-
const code = ast.toCode('v');
|
|
109
|
+
const code = ast.toCode('v', { verbose: true });
|
|
98
110
|
const executableCode = stripExports(code);
|
|
99
111
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
100
112
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -121,6 +133,12 @@ describe('Prednisone Integration Test', () => {
|
|
|
121
133
|
expect(code).toMatchSnapshot();
|
|
122
134
|
});
|
|
123
135
|
|
|
136
|
+
test('generates valid verbose code via toCode()', () => {
|
|
137
|
+
const ast = parse(PREDNISONE_SMILES);
|
|
138
|
+
const code = ast.toCode('v', { verbose: true });
|
|
139
|
+
expect(code).toMatchSnapshot();
|
|
140
|
+
});
|
|
141
|
+
|
|
124
142
|
test('generated code is valid JavaScript', () => {
|
|
125
143
|
const ast = parse(PREDNISONE_SMILES);
|
|
126
144
|
const code = ast.toCode('v');
|
|
@@ -128,14 +146,14 @@ describe('Prednisone Integration Test', () => {
|
|
|
128
146
|
|
|
129
147
|
let factory;
|
|
130
148
|
expect(() => {
|
|
131
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
149
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
132
150
|
}).not.toThrow();
|
|
133
151
|
expect(typeof factory).toBe('function');
|
|
134
152
|
});
|
|
135
153
|
|
|
136
154
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
137
155
|
const ast = parse(PREDNISONE_SMILES);
|
|
138
|
-
const code = ast.toCode('v');
|
|
156
|
+
const code = ast.toCode('v', { verbose: true });
|
|
139
157
|
const executableCode = stripExports(code);
|
|
140
158
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
141
159
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -162,6 +180,12 @@ describe('Prednisolone Integration Test', () => {
|
|
|
162
180
|
expect(code).toMatchSnapshot();
|
|
163
181
|
});
|
|
164
182
|
|
|
183
|
+
test('generates valid verbose code via toCode()', () => {
|
|
184
|
+
const ast = parse(PREDNISOLONE_SMILES);
|
|
185
|
+
const code = ast.toCode('v', { verbose: true });
|
|
186
|
+
expect(code).toMatchSnapshot();
|
|
187
|
+
});
|
|
188
|
+
|
|
165
189
|
test('generated code is valid JavaScript', () => {
|
|
166
190
|
const ast = parse(PREDNISOLONE_SMILES);
|
|
167
191
|
const code = ast.toCode('v');
|
|
@@ -169,14 +193,14 @@ describe('Prednisolone Integration Test', () => {
|
|
|
169
193
|
|
|
170
194
|
let factory;
|
|
171
195
|
expect(() => {
|
|
172
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
196
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
173
197
|
}).not.toThrow();
|
|
174
198
|
expect(typeof factory).toBe('function');
|
|
175
199
|
});
|
|
176
200
|
|
|
177
201
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
178
202
|
const ast = parse(PREDNISOLONE_SMILES);
|
|
179
|
-
const code = ast.toCode('v');
|
|
203
|
+
const code = ast.toCode('v', { verbose: true });
|
|
180
204
|
const executableCode = stripExports(code);
|
|
181
205
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
182
206
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -203,6 +227,12 @@ describe('Methylprednisolone Integration Test', () => {
|
|
|
203
227
|
expect(code).toMatchSnapshot();
|
|
204
228
|
});
|
|
205
229
|
|
|
230
|
+
test('generates valid verbose code via toCode()', () => {
|
|
231
|
+
const ast = parse(METHYLPREDNISOLONE_SMILES);
|
|
232
|
+
const code = ast.toCode('v', { verbose: true });
|
|
233
|
+
expect(code).toMatchSnapshot();
|
|
234
|
+
});
|
|
235
|
+
|
|
206
236
|
test('generated code is valid JavaScript', () => {
|
|
207
237
|
const ast = parse(METHYLPREDNISOLONE_SMILES);
|
|
208
238
|
const code = ast.toCode('v');
|
|
@@ -210,14 +240,14 @@ describe('Methylprednisolone Integration Test', () => {
|
|
|
210
240
|
|
|
211
241
|
let factory;
|
|
212
242
|
expect(() => {
|
|
213
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
243
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
214
244
|
}).not.toThrow();
|
|
215
245
|
expect(typeof factory).toBe('function');
|
|
216
246
|
});
|
|
217
247
|
|
|
218
248
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
219
249
|
const ast = parse(METHYLPREDNISOLONE_SMILES);
|
|
220
|
-
const code = ast.toCode('v');
|
|
250
|
+
const code = ast.toCode('v', { verbose: true });
|
|
221
251
|
const executableCode = stripExports(code);
|
|
222
252
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
223
253
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -244,6 +274,12 @@ describe('Dexamethasone Integration Test', () => {
|
|
|
244
274
|
expect(code).toMatchSnapshot();
|
|
245
275
|
});
|
|
246
276
|
|
|
277
|
+
test('generates valid verbose code via toCode()', () => {
|
|
278
|
+
const ast = parse(DEXAMETHASONE_SMILES);
|
|
279
|
+
const code = ast.toCode('v', { verbose: true });
|
|
280
|
+
expect(code).toMatchSnapshot();
|
|
281
|
+
});
|
|
282
|
+
|
|
247
283
|
test('generated code is valid JavaScript', () => {
|
|
248
284
|
const ast = parse(DEXAMETHASONE_SMILES);
|
|
249
285
|
const code = ast.toCode('v');
|
|
@@ -251,14 +287,14 @@ describe('Dexamethasone Integration Test', () => {
|
|
|
251
287
|
|
|
252
288
|
let factory;
|
|
253
289
|
expect(() => {
|
|
254
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
290
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
255
291
|
}).not.toThrow();
|
|
256
292
|
expect(typeof factory).toBe('function');
|
|
257
293
|
});
|
|
258
294
|
|
|
259
295
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
260
296
|
const ast = parse(DEXAMETHASONE_SMILES);
|
|
261
|
-
const code = ast.toCode('v');
|
|
297
|
+
const code = ast.toCode('v', { verbose: true });
|
|
262
298
|
const executableCode = stripExports(code);
|
|
263
299
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
264
300
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -285,6 +321,12 @@ describe('Triamcinolone Integration Test', () => {
|
|
|
285
321
|
expect(code).toMatchSnapshot();
|
|
286
322
|
});
|
|
287
323
|
|
|
324
|
+
test('generates valid verbose code via toCode()', () => {
|
|
325
|
+
const ast = parse(TRIAMCINOLONE_SMILES);
|
|
326
|
+
const code = ast.toCode('v', { verbose: true });
|
|
327
|
+
expect(code).toMatchSnapshot();
|
|
328
|
+
});
|
|
329
|
+
|
|
288
330
|
test('generated code is valid JavaScript', () => {
|
|
289
331
|
const ast = parse(TRIAMCINOLONE_SMILES);
|
|
290
332
|
const code = ast.toCode('v');
|
|
@@ -292,14 +334,14 @@ describe('Triamcinolone Integration Test', () => {
|
|
|
292
334
|
|
|
293
335
|
let factory;
|
|
294
336
|
expect(() => {
|
|
295
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
337
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
296
338
|
}).not.toThrow();
|
|
297
339
|
expect(typeof factory).toBe('function');
|
|
298
340
|
});
|
|
299
341
|
|
|
300
342
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
301
343
|
const ast = parse(TRIAMCINOLONE_SMILES);
|
|
302
|
-
const code = ast.toCode('v');
|
|
344
|
+
const code = ast.toCode('v', { verbose: true });
|
|
303
345
|
const executableCode = stripExports(code);
|
|
304
346
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
305
347
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -326,6 +368,12 @@ describe('Budesonide Integration Test', () => {
|
|
|
326
368
|
expect(code).toMatchSnapshot();
|
|
327
369
|
});
|
|
328
370
|
|
|
371
|
+
test('generates valid verbose code via toCode()', () => {
|
|
372
|
+
const ast = parse(BUDESONIDE_SMILES);
|
|
373
|
+
const code = ast.toCode('v', { verbose: true });
|
|
374
|
+
expect(code).toMatchSnapshot();
|
|
375
|
+
});
|
|
376
|
+
|
|
329
377
|
test('generated code is valid JavaScript', () => {
|
|
330
378
|
const ast = parse(BUDESONIDE_SMILES);
|
|
331
379
|
const code = ast.toCode('v');
|
|
@@ -333,14 +381,14 @@ describe('Budesonide Integration Test', () => {
|
|
|
333
381
|
|
|
334
382
|
let factory;
|
|
335
383
|
expect(() => {
|
|
336
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
384
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
337
385
|
}).not.toThrow();
|
|
338
386
|
expect(typeof factory).toBe('function');
|
|
339
387
|
});
|
|
340
388
|
|
|
341
389
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
342
390
|
const ast = parse(BUDESONIDE_SMILES);
|
|
343
|
-
const code = ast.toCode('v');
|
|
391
|
+
const code = ast.toCode('v', { verbose: true });
|
|
344
392
|
const executableCode = stripExports(code);
|
|
345
393
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
346
394
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -367,6 +415,12 @@ describe('Fluticasone Integration Test', () => {
|
|
|
367
415
|
expect(code).toMatchSnapshot();
|
|
368
416
|
});
|
|
369
417
|
|
|
418
|
+
test('generates valid verbose code via toCode()', () => {
|
|
419
|
+
const ast = parse(FLUTICASONE_SMILES);
|
|
420
|
+
const code = ast.toCode('v', { verbose: true });
|
|
421
|
+
expect(code).toMatchSnapshot();
|
|
422
|
+
});
|
|
423
|
+
|
|
370
424
|
test('generated code is valid JavaScript', () => {
|
|
371
425
|
const ast = parse(FLUTICASONE_SMILES);
|
|
372
426
|
const code = ast.toCode('v');
|
|
@@ -374,14 +428,14 @@ describe('Fluticasone Integration Test', () => {
|
|
|
374
428
|
|
|
375
429
|
let factory;
|
|
376
430
|
expect(() => {
|
|
377
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
431
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
378
432
|
}).not.toThrow();
|
|
379
433
|
expect(typeof factory).toBe('function');
|
|
380
434
|
});
|
|
381
435
|
|
|
382
436
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
383
437
|
const ast = parse(FLUTICASONE_SMILES);
|
|
384
|
-
const code = ast.toCode('v');
|
|
438
|
+
const code = ast.toCode('v', { verbose: true });
|
|
385
439
|
const executableCode = stripExports(code);
|
|
386
440
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
387
441
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -408,6 +462,12 @@ describe('Beclomethasone Integration Test', () => {
|
|
|
408
462
|
expect(code).toMatchSnapshot();
|
|
409
463
|
});
|
|
410
464
|
|
|
465
|
+
test('generates valid verbose code via toCode()', () => {
|
|
466
|
+
const ast = parse(BECLOMETHASONE_SMILES);
|
|
467
|
+
const code = ast.toCode('v', { verbose: true });
|
|
468
|
+
expect(code).toMatchSnapshot();
|
|
469
|
+
});
|
|
470
|
+
|
|
411
471
|
test('generated code is valid JavaScript', () => {
|
|
412
472
|
const ast = parse(BECLOMETHASONE_SMILES);
|
|
413
473
|
const code = ast.toCode('v');
|
|
@@ -415,14 +475,14 @@ describe('Beclomethasone Integration Test', () => {
|
|
|
415
475
|
|
|
416
476
|
let factory;
|
|
417
477
|
expect(() => {
|
|
418
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
478
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
419
479
|
}).not.toThrow();
|
|
420
480
|
expect(typeof factory).toBe('function');
|
|
421
481
|
});
|
|
422
482
|
|
|
423
483
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
424
484
|
const ast = parse(BECLOMETHASONE_SMILES);
|
|
425
|
-
const code = ast.toCode('v');
|
|
485
|
+
const code = ast.toCode('v', { verbose: true });
|
|
426
486
|
const executableCode = stripExports(code);
|
|
427
487
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
428
488
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -449,6 +509,12 @@ describe('Fludrocortisone Integration Test', () => {
|
|
|
449
509
|
expect(code).toMatchSnapshot();
|
|
450
510
|
});
|
|
451
511
|
|
|
512
|
+
test('generates valid verbose code via toCode()', () => {
|
|
513
|
+
const ast = parse(FLUDROCORTISONE_SMILES);
|
|
514
|
+
const code = ast.toCode('v', { verbose: true });
|
|
515
|
+
expect(code).toMatchSnapshot();
|
|
516
|
+
});
|
|
517
|
+
|
|
452
518
|
test('generated code is valid JavaScript', () => {
|
|
453
519
|
const ast = parse(FLUDROCORTISONE_SMILES);
|
|
454
520
|
const code = ast.toCode('v');
|
|
@@ -456,14 +522,14 @@ describe('Fludrocortisone Integration Test', () => {
|
|
|
456
522
|
|
|
457
523
|
let factory;
|
|
458
524
|
expect(() => {
|
|
459
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
525
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
460
526
|
}).not.toThrow();
|
|
461
527
|
expect(typeof factory).toBe('function');
|
|
462
528
|
});
|
|
463
529
|
|
|
464
530
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
465
531
|
const ast = parse(FLUDROCORTISONE_SMILES);
|
|
466
|
-
const code = ast.toCode('v');
|
|
532
|
+
const code = ast.toCode('v', { verbose: true });
|
|
467
533
|
const executableCode = stripExports(code);
|
|
468
534
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
469
535
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -490,6 +556,12 @@ describe('Mometasone Integration Test', () => {
|
|
|
490
556
|
expect(code).toMatchSnapshot();
|
|
491
557
|
});
|
|
492
558
|
|
|
559
|
+
test('generates valid verbose code via toCode()', () => {
|
|
560
|
+
const ast = parse(MOMETASONE_SMILES);
|
|
561
|
+
const code = ast.toCode('v', { verbose: true });
|
|
562
|
+
expect(code).toMatchSnapshot();
|
|
563
|
+
});
|
|
564
|
+
|
|
493
565
|
test('generated code is valid JavaScript', () => {
|
|
494
566
|
const ast = parse(MOMETASONE_SMILES);
|
|
495
567
|
const code = ast.toCode('v');
|
|
@@ -497,14 +569,14 @@ describe('Mometasone Integration Test', () => {
|
|
|
497
569
|
|
|
498
570
|
let factory;
|
|
499
571
|
expect(() => {
|
|
500
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
572
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
501
573
|
}).not.toThrow();
|
|
502
574
|
expect(typeof factory).toBe('function');
|
|
503
575
|
});
|
|
504
576
|
|
|
505
577
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
506
578
|
const ast = parse(MOMETASONE_SMILES);
|
|
507
|
-
const code = ast.toCode('v');
|
|
579
|
+
const code = ast.toCode('v', { verbose: true });
|
|
508
580
|
const executableCode = stripExports(code);
|
|
509
581
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
510
582
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -531,6 +603,12 @@ describe('Cortisol Integration Test', () => {
|
|
|
531
603
|
expect(code).toMatchSnapshot();
|
|
532
604
|
});
|
|
533
605
|
|
|
606
|
+
test('generates valid verbose code via toCode()', () => {
|
|
607
|
+
const ast = parse(CORTISOL_SMILES);
|
|
608
|
+
const code = ast.toCode('v', { verbose: true });
|
|
609
|
+
expect(code).toMatchSnapshot();
|
|
610
|
+
});
|
|
611
|
+
|
|
534
612
|
test('generated code is valid JavaScript', () => {
|
|
535
613
|
const ast = parse(CORTISOL_SMILES);
|
|
536
614
|
const code = ast.toCode('v');
|
|
@@ -538,14 +616,14 @@ describe('Cortisol Integration Test', () => {
|
|
|
538
616
|
|
|
539
617
|
let factory;
|
|
540
618
|
expect(() => {
|
|
541
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
619
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
542
620
|
}).not.toThrow();
|
|
543
621
|
expect(typeof factory).toBe('function');
|
|
544
622
|
});
|
|
545
623
|
|
|
546
624
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
547
625
|
const ast = parse(CORTISOL_SMILES);
|
|
548
|
-
const code = ast.toCode('v');
|
|
626
|
+
const code = ast.toCode('v', { verbose: true });
|
|
549
627
|
const executableCode = stripExports(code);
|
|
550
628
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
551
629
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -572,6 +650,12 @@ describe('Betamethasone Integration Test', () => {
|
|
|
572
650
|
expect(code).toMatchSnapshot();
|
|
573
651
|
});
|
|
574
652
|
|
|
653
|
+
test('generates valid verbose code via toCode()', () => {
|
|
654
|
+
const ast = parse(BETAMETHASONE_SMILES);
|
|
655
|
+
const code = ast.toCode('v', { verbose: true });
|
|
656
|
+
expect(code).toMatchSnapshot();
|
|
657
|
+
});
|
|
658
|
+
|
|
575
659
|
test('generated code is valid JavaScript', () => {
|
|
576
660
|
const ast = parse(BETAMETHASONE_SMILES);
|
|
577
661
|
const code = ast.toCode('v');
|
|
@@ -579,14 +663,14 @@ describe('Betamethasone Integration Test', () => {
|
|
|
579
663
|
|
|
580
664
|
let factory;
|
|
581
665
|
expect(() => {
|
|
582
|
-
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', executableCode);
|
|
666
|
+
factory = createFunction('Ring', 'Linear', 'FusedRing', 'Molecule', 'RawFragment', 'Fragment', executableCode);
|
|
583
667
|
}).not.toThrow();
|
|
584
668
|
expect(typeof factory).toBe('function');
|
|
585
669
|
});
|
|
586
670
|
|
|
587
671
|
test('codegen round-trip: generated code produces valid SMILES', () => {
|
|
588
672
|
const ast = parse(BETAMETHASONE_SMILES);
|
|
589
|
-
const code = ast.toCode('v');
|
|
673
|
+
const code = ast.toCode('v', { verbose: true });
|
|
590
674
|
const executableCode = stripExports(code);
|
|
591
675
|
const varMatch = code.match(/export const (v\d+) = /g);
|
|
592
676
|
const lastVar = varMatch[varMatch.length - 1].match(/export const (v\d+)/)[1];
|
|
@@ -2,6 +2,7 @@ import { parse } from '../src/parser/index.js';
|
|
|
2
2
|
import {
|
|
3
3
|
Ring, Linear, FusedRing, Molecule, RawFragment,
|
|
4
4
|
} from '../src/constructors.js';
|
|
5
|
+
import { Fragment } from '../src/fragment.js';
|
|
5
6
|
|
|
6
7
|
// Use indirect Function constructor access to satisfy linter
|
|
7
8
|
// This is a legitimate use case for testing code generation
|
|
@@ -38,9 +39,10 @@ export function executeCode(code, returnVar) {
|
|
|
38
39
|
'FusedRing',
|
|
39
40
|
'Molecule',
|
|
40
41
|
'RawFragment',
|
|
42
|
+
'Fragment',
|
|
41
43
|
`${code}\nreturn ${returnVar};`,
|
|
42
44
|
);
|
|
43
|
-
return factory(Ring, Linear, FusedRing, Molecule, RawFragment);
|
|
45
|
+
return factory(Ring, Linear, FusedRing, Molecule, RawFragment, Fragment);
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
/**
|
|
@@ -51,7 +53,7 @@ export function executeCode(code, returnVar) {
|
|
|
51
53
|
*/
|
|
52
54
|
export function codegenRoundTrip(smiles) {
|
|
53
55
|
const ast = parse(smiles);
|
|
54
|
-
const code = ast.toCode('v');
|
|
56
|
+
const code = ast.toCode('v', { verbose: true });
|
|
55
57
|
|
|
56
58
|
// Find the last variable name in the generated code
|
|
57
59
|
const varMatches = code.match(/export (?:const|let) (v\d+)/g);
|