UNPKG

5.63 kBPlain TextView Raw
1import { HIR } from '@atjson/hir';
2import OffsetSource from '@atjson/offset-annotations';
3import * as fs from 'fs';
4import * as path from 'path';
5import PRISMSource from '../src';
6
7describe('@atjson/source-prism', () => {
8 it('parses xml declaration', () => {
9 let doc = PRISMSource.fromRaw('<?xml version="1.0" encoding="utf-8"?>');
10
11 expect(doc.where({}).toJSON()).toMatchObject([
12 {
13 type: '-atjson-parse-token',
14 start: 0,
15 end: doc.content.length,
16 attributes: {
17 '-atjson-reason': '<?xml>'
18 }
19 }
20 ]);
21 });
22
23 it('does not require xml declaration', () => {
24 let doc = PRISMSource.fromRaw('<body>some text</body>');
25
26 expect(doc.where({}).sort().toJSON()).toMatchObject([
27 { type: '-atjson-parse-token', start: 0, end: 6, attributes: { '-atjson-reason': '<body>' } },
28 { type: '-html-body', start: 0, end: 22 },
29 { type: '-atjson-parse-token', start: 15, end: 22, attributes: { '-atjson-reason': '</body>' } }
30 ]);
31 });
32
33 it('parses xml tags', () => {
34 let doc = PRISMSource.fromRaw(`<?xml version="1.0" encoding="utf-8"?><pam:message><pam:article><head /><body>text</body></pam:article></pam:message>`);
35 let hir = new HIR(doc);
36
37 expect(hir.toJSON()).toMatchObject({
38 children: [
39 {
40 type: 'message',
41 children: [
42 {
43 type: 'article',
44 children: [
45 { type: 'head' },
46 { type: 'body', children: ['text'] }
47 ]
48 }
49 ]
50 }
51 ]
52 });
53
54 expect(doc.where({}).sort().toJSON()).toMatchObject([
55 { type: '-atjson-parse-token', start: 0, end: 38, attributes: { '-atjson-reason': '<?xml>' } },
56 { type: '-atjson-parse-token', start: 38, end: 51, attributes: { '-atjson-reason': '<pam:message>' } },
57 { type: '-pam-message', start: 38, end: 117 },
58 { type: '-atjson-parse-token', start: 51, end: 64, attributes: { '-atjson-reason': '<pam:article>' } },
59 { type: '-pam-article', start: 51, end: 103 },
60 { type: '-html-head', start: 64, end: 72 },
61 { type: '-atjson-parse-token', start: 64, end: 72, attributes: { '-atjson-reason': '<head/>' } },
62 { type: '-atjson-parse-token', start: 72, end: 78, attributes: { '-atjson-reason': '<body>' } },
63 { type: '-html-body', start: 72, end: 89 },
64 { type: '-atjson-parse-token', start: 82, end: 89, attributes: { '-atjson-reason': '</body>' } },
65 { type: '-atjson-parse-token', start: 89, end: 103, attributes: { '-atjson-reason': '</pam:article>' } },
66 { type: '-atjson-parse-token', start: 103, end: 117, attributes: { '-atjson-reason': '</pam:message>' } }
67 ]);
68 });
69
70 describe('xml entities', () => {
71 test.each([
72 [ '&#8704;', '∀' ], // dec entity
73 [ '&#x201C;', '“' ], // hex entity
74 [ '&quot;', '"' ], // five named xml entities
75 [ '&amp;', '&' ],
76 [ '&apos;', '\'' ],
77 [ '&lt;', '<' ],
78 [ '&gt;', '>' ],
79 [ '&rsquo;', '&rsquo;' ] // other named entities are not supported
80 ])('converts %s to %s', (entity, expected) => {
81 let doc = PRISMSource.fromRaw(`<?xml version="1.0" encoding="utf-8"?><body>${entity}</body>`);
82
83 expect(doc.content).toEqual(`<?xml version="1.0" encoding="utf-8"?><body>${expected}</body>`);
84 });
85
86 it('repositions annotations after replacing entities', () => {
87 let doc = PRISMSource.fromRaw('<pam:article><head><dc:title>Title</dc:title></head><body><p>&#8704;x&#8712;Λ, x&#8744;&#172;x&#x220E;</p></body></pam:article>');
88
89 expect(doc.content).toEqual('<pam:article><head><dc:title>Title</dc:title></head><body><p>∀x∈Λ, x∨¬x∎</p></body></pam:article>');
90 expect(doc.where({}).sort().toJSON()).toMatchObject([
91 { type: '-atjson-parse-token', start: 0, end: 13, attributes: { '-atjson-reason': '<pam:article>' } },
92 { type: '-pam-article', start: 0, end: 97 },
93 { type: '-atjson-parse-token', start: 13, end: 19, attributes: { '-atjson-reason': '<head>' } },
94 { type: '-html-head', start: 13, end: 52 },
95 { type: '-atjson-parse-token', start: 19, end: 29, attributes: { '-atjson-reason': '<dc:title>' } },
96 { type: '-dc-title', start: 19, end: 45 },
97 { type: '-atjson-parse-token', start: 34, end: 45, attributes: { '-atjson-reason': '</dc:title>' } },
98 { type: '-atjson-parse-token', start: 45, end: 52, attributes: { '-atjson-reason': '</head>' } },
99 { type: '-atjson-parse-token', start: 52, end: 58, attributes: { '-atjson-reason': '<body>' } },
100 { type: '-html-body', start: 52, end: 83 },
101 { type: '-atjson-parse-token', start: 58, end: 61, attributes: { '-atjson-reason': '<p>' } },
102 { type: '-html-p', start: 58, end: 76 },
103 { type: '-atjson-parse-token', start: 72, end: 76, attributes: { '-atjson-reason': '</p>' } },
104 { type: '-atjson-parse-token', start: 76, end: 83, attributes: { '-atjson-reason': '</body>' } },
105 { type: '-atjson-parse-token', start: 83, end: 97, attributes: { '-atjson-reason': '</pam:article>' } }
106 ]);
107 });
108 });
109
110 describe('prism snapshots', () => {
111 test.each([
112 [ 'gq-fresh-paint.xml' ],
113 [ 'gq-santoni.xml' ],
114 [ 'gq-yuketen.xml' ]
115 ])('parses %s', xmlFile => {
116 let fixturePath = path.join(__dirname, 'fixtures', xmlFile);
117 let xml = fs.readFileSync(fixturePath).toString();
118
119 let doc = PRISMSource.fromRaw(xml);
120 let hir = new HIR(doc);
121
122 expect(hir.toJSON()).toMatchSnapshot();
123 expect(doc.convertTo(OffsetSource).toJSON()).toMatchSnapshot();
124 });
125 });
126});