-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsdf-parser.test.ts
More file actions
160 lines (130 loc) · 5.3 KB
/
Copy pathsdf-parser.test.ts
File metadata and controls
160 lines (130 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import { readFileSync } from 'fs';
import { join } from 'path';
import { describe, it, expect } from 'vitest';
import { parseSdf } from '../src/sdf-parser';
import { buildYaml } from '../src/import-utils';
const SDF_PATH = join(__dirname, 'data', 'missing_names.sdf');
const sdfContent = readFileSync(SDF_PATH, 'utf-8');
const NO_NAME_PATH = join(__dirname, 'data', 'no_name_at_all.sdf');
const noNameContent = readFileSync(NO_NAME_PATH, 'utf-8');
describe('parseSdf – missing_names.sdf', () => {
const mols = parseSdf(sdfContent);
it('parses exactly 3 molecules', () => {
expect(mols).toHaveLength(3);
});
it('mol 1 – title "with_name" is on the first molblock line', () => {
const firstLine = mols[0].molblock.split('\n')[0];
expect(firstLine).toBe('with_name');
});
it('mol 2 – blank title line is preserved (molblock starts with \\n)', () => {
expect(mols[1].molblock.startsWith('\n')).toBe(true);
const firstLine = mols[1].molblock.split('\n')[0];
expect(firstLine).toBe('');
});
it('mol 3 – title "caffeine" is on the first molblock line', () => {
const firstLine = mols[2].molblock.split('\n')[0];
expect(firstLine).toBe('caffeine');
});
it('all 3 molecules have M END in their molblock', () => {
for (const mol of mols) {
expect(mol.molblock).toContain('M END');
}
});
it('all 3 molecules have PUBCHEM_COMPOUND_CID = "2519"', () => {
for (const mol of mols) {
expect(mol.properties['PUBCHEM_COMPOUND_CID']).toBe('2519');
}
});
});
describe('parseSdf – no_name_at_all.sdf', () => {
const mols = parseSdf(noNameContent);
it('parses exactly 2 molecules', () => {
expect(mols).toHaveLength(2);
});
it('mol 1 – blank title line is preserved (molblock starts with \\n)', () => {
expect(mols[0].molblock.startsWith('\n')).toBe(true);
const firstLine = mols[0].molblock.split('\n')[0];
expect(firstLine).toBe('');
});
it('mol 2 – blank title line is preserved (molblock starts with \\n)', () => {
expect(mols[1].molblock.startsWith('\n')).toBe(true);
const firstLine = mols[1].molblock.split('\n')[0];
expect(firstLine).toBe('');
});
it('both molecules have M END in their molblock', () => {
for (const mol of mols) {
expect(mol.molblock).toContain('M END');
}
});
it('neither molecule has properties', () => {
for (const mol of mols) {
expect(Object.keys(mol.properties)).toHaveLength(0);
}
});
});
const NO_NAME_SPACES_PATH = join(__dirname, 'data', 'no_name_spaces.sdf');
const noNameSpacesContent = readFileSync(NO_NAME_SPACES_PATH, 'utf-8');
describe('parseSdf – no_name_spaces.sdf', () => {
const mols = parseSdf(noNameSpacesContent);
it('parses exactly 2 molecules', () => {
expect(mols).toHaveLength(2);
});
it('mol 1 – title line is 3 spaces (not empty, not named)', () => {
// Title line is " " (3 spaces): distinct from both blank (\n) and named titles.
// parseSdf must preserve it as-is so buildYaml can detect the whitespace-only
// first line and choose |2- over |.
const firstLine = mols[0].molblock.split('\n')[0];
expect(firstLine).toBe(' ');
});
it('mol 1 – molblock does NOT start with \\n (whitespace title, not blank title)', () => {
expect(mols[0].molblock.startsWith('\n')).toBe(false);
expect(mols[0].molblock.startsWith(' ')).toBe(true);
});
it('mol 1 – buildYaml uses |2- to prevent YAML indent auto-detection corruption', () => {
// Without |2-, YAML detects indent=4 from the first non-whitespace line
// (" -INDIGO...") and strips 4 spaces from every line, corrupting the molblock.
const yaml = buildYaml({ _m2b_molblock: mols[0].molblock });
expect(yaml).toMatch(/^_m2b_molblock: \|2-$/m);
});
it('mol 1 – molblock content is preserved correctly through buildYaml', () => {
const yaml = buildYaml({ _m2b_molblock: mols[0].molblock });
const lines = yaml.split('\n');
const headerIdx = lines.findIndex((l) => l.startsWith('_m2b_molblock:'));
// Title line: 2-space YAML indent + 3 spaces = 5 spaces
expect(lines[headerIdx + 1]).toBe(' ');
// Program line: 2-space YAML indent + " -INDIGO-..." (2 leading spaces preserved)
expect(lines[headerIdx + 2]).toBe(' -INDIGO-04142622472D');
});
it('mol 2 – blank title line (starts with \\n after leading-newline strip)', () => {
expect(mols[1].molblock.startsWith('\n')).toBe(true);
});
it('both molecules have M END in their molblock', () => {
for (const mol of mols) {
expect(mol.molblock).toContain('M END');
}
});
it('neither molecule has properties', () => {
for (const mol of mols) {
expect(Object.keys(mol.properties)).toHaveLength(0);
}
});
});
const DUP_PATH = join(__dirname, 'data', 'dup_names.sdf');
const dupContent = readFileSync(DUP_PATH, 'utf-8');
describe('parseSdf – dup_names.sdf', () => {
const mols = parseSdf(dupContent);
it('parses exactly 2 molecules', () => {
expect(mols).toHaveLength(2);
});
it('both molecules have molblock title "compound"', () => {
for (const mol of mols) {
const firstLine = mol.molblock.split('\n')[0];
expect(firstLine).toBe('compound');
}
});
it('both molecules contain M END', () => {
for (const mol of mols) {
expect(mol.molblock).toContain('M END');
}
});
});