extwee 2.2.0 → 2.2.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.
- package/.github/codeql-analysis.yml +51 -0
- package/README.md +9 -3
- package/build/extwee +0 -0
- package/build/extwee.web.min.js +1 -1
- package/docs/_sidebar.md +1 -0
- package/docs/examples/dynamicPassages.md +1 -1
- package/docs/examples/twsToTwee.md +1 -1
- package/docs/objects/story.md +1 -2
- package/index.js +3 -1
- package/package.json +22 -19
- package/src/IFID/generate.js +20 -0
- package/src/JSON/parse.js +44 -1
- package/src/Passage.js +61 -31
- package/src/Story.js +272 -110
- package/src/StoryFormat/parse.js +190 -80
- package/src/StoryFormat.js +78 -88
- package/src/TWS/parse.js +3 -3
- package/src/Twee/parse.js +3 -4
- package/src/Twine1HTML/compile.js +3 -1
- package/src/Twine1HTML/parse.js +3 -4
- package/src/Twine2ArchiveHTML/compile.js +9 -1
- package/src/Twine2ArchiveHTML/parse.js +33 -3
- package/src/Twine2HTML/compile.js +32 -7
- package/src/Twine2HTML/parse.js +51 -55
- package/test/IFID/IFID.Generate.test.js +10 -0
- package/test/JSON/JSON.Parse.test.js +24 -24
- package/test/Passage.test.js +69 -0
- package/test/Story.test.js +298 -49
- package/test/StoryFormat/StoryFormat.Parse.test.js +442 -55
- package/test/StoryFormat.test.js +9 -2
- package/test/TWS/Parse.test.js +1 -1
- package/test/Twine1HTML/Twine1HTML.Compile.test.js +1 -1
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Compile.test.js +1 -1
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.test.js +20 -4
- package/test/Twine2HTML/Twine2HTML.Compile.test.js +36 -121
- package/test/Twine2HTML/Twine2HTML.Parse.test.js +63 -43
- package/test/Twine2HTML/Twine2HTMLCompiler/format.js +9 -0
- package/test/Twine2HTML/Twine2HTMLParser/missingZoom.html +1 -1
- package/test/Twine2HTML/Twine2HTMLParser/unescaping.html +33 -0
- package/tsconfig.json +21 -0
- package/types/index.d.ts +14 -0
- package/types/src/JSON/parse.d.ts +8 -0
- package/types/src/Passage.d.ts +72 -0
- package/types/src/Story.d.ts +161 -0
- package/types/src/StoryFormat/parse.d.ts +7 -0
- package/types/src/StoryFormat.d.ts +97 -0
- package/types/src/TWS/parse.d.ts +10 -0
- package/types/src/Twee/parse.d.ts +10 -0
- package/types/src/Twine1HTML/compile.d.ts +17 -0
- package/types/src/Twine1HTML/parse.d.ts +10 -0
- package/types/src/Twine2ArchiveHTML/compile.d.ts +6 -0
- package/types/src/Twine2ArchiveHTML/parse.d.ts +6 -0
- package/types/src/Twine2HTML/compile.d.ts +9 -0
- package/types/src/Twine2HTML/parse.d.ts +17 -0
- package/types/src/extwee.d.ts +2 -0
- package/web-index.js +3 -1
- package/test/StoryFormat/StoryFormatParser/example.js +0 -3
- package/test/StoryFormat/StoryFormatParser/example2.js +0 -3
- package/test/StoryFormat/StoryFormatParser/format.js +0 -1
- package/test/StoryFormat/StoryFormatParser/format_doublename.js +0 -1
- package/test/StoryFormat/StoryFormatParser/harlowe.js +0 -3
- package/test/StoryFormat/StoryFormatParser/missingAuthor.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingDescription.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingImage.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingLicense.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingName.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingProofing.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingSource.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingURL.js +0 -1
- package/test/StoryFormat/StoryFormatParser/missingVersion.js +0 -1
- package/test/StoryFormat/StoryFormatParser/versionWrong.js +0 -1
- package/test/Twine2HTML/Twine2HTMLParser/missingName.html +0 -33
- package/test/Twine2HTML/Twine2HTMLParser/missingPID.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/missingPassageName.html +0 -15
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { parse as parseStoryFormat } from '../../src/StoryFormat/parse.js';
|
|
2
2
|
import { parse as parseTwine2HTML } from '../../src/Twine2HTML/parse.js';
|
|
3
3
|
import { compile as compileTwine2HTML } from '../../src/Twine2HTML/compile.js';
|
|
4
|
-
import Story from '../../src/Story.js';
|
|
4
|
+
import { Story } from '../../src/Story.js';
|
|
5
5
|
import Passage from '../../src/Passage.js';
|
|
6
|
+
import StoryFormat from '../../src/StoryFormat.js';
|
|
7
|
+
import { generate as generateIFID } from '../../src/IFID/generate.js';
|
|
6
8
|
import { readFileSync } from 'node:fs';
|
|
7
9
|
|
|
8
10
|
describe('Twine2HTMLCompiler', () => {
|
|
@@ -16,29 +18,6 @@ describe('Twine2HTMLCompiler', () => {
|
|
|
16
18
|
expect(() => { compileTwine2HTML(s, {}); }).toThrow();
|
|
17
19
|
});
|
|
18
20
|
|
|
19
|
-
it('Read, write, and read HTML', () => {
|
|
20
|
-
// Read HTML.
|
|
21
|
-
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/twineExample3.html', 'utf-8');
|
|
22
|
-
|
|
23
|
-
// Parse HTML.
|
|
24
|
-
const story = parseTwine2HTML(fr);
|
|
25
|
-
|
|
26
|
-
// Read StoryFormat.
|
|
27
|
-
const fr2 = readFileSync('test/StoryFormat/StoryFormatParser/format.js', 'utf-8');
|
|
28
|
-
|
|
29
|
-
// Parse StoryFormat.
|
|
30
|
-
const storyFormat = parseStoryFormat(fr2);
|
|
31
|
-
|
|
32
|
-
// Write HTML.
|
|
33
|
-
const fr3 = compileTwine2HTML(story, storyFormat);
|
|
34
|
-
|
|
35
|
-
// Parse HTML.
|
|
36
|
-
const story2 = parseTwine2HTML(fr3);
|
|
37
|
-
|
|
38
|
-
// Test both names to be the same.
|
|
39
|
-
expect(story.name).toBe(story2.name);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
21
|
it('Should write one and two-tag passages', () => {
|
|
43
22
|
// Read HTML.
|
|
44
23
|
const fr = readFileSync('test/Twine2HTML/Twine2HTMLCompiler/TestTags.html', 'utf-8');
|
|
@@ -47,7 +26,7 @@ describe('Twine2HTMLCompiler', () => {
|
|
|
47
26
|
const story = parseTwine2HTML(fr);
|
|
48
27
|
|
|
49
28
|
// Read StoryFormat.
|
|
50
|
-
const fr2 = readFileSync('test/
|
|
29
|
+
const fr2 = readFileSync('test/Twine2HTML/Twine2HTMLCompiler/format.js', 'utf-8');
|
|
51
30
|
|
|
52
31
|
// Parse StoryFormat.
|
|
53
32
|
const storyFormat = parseStoryFormat(fr2);
|
|
@@ -62,12 +41,12 @@ describe('Twine2HTMLCompiler', () => {
|
|
|
62
41
|
let tags2 = '';
|
|
63
42
|
|
|
64
43
|
// Combine contents of tags.
|
|
65
|
-
story.
|
|
44
|
+
story.passages.forEach((p) => {
|
|
66
45
|
tags += p.tags.join('');
|
|
67
46
|
});
|
|
68
47
|
|
|
69
48
|
// Combine contents of tags.
|
|
70
|
-
story2.
|
|
49
|
+
story2.passages.forEach((p) => {
|
|
71
50
|
tags2 += p.tags.join('');
|
|
72
51
|
});
|
|
73
52
|
|
|
@@ -76,148 +55,84 @@ describe('Twine2HTMLCompiler', () => {
|
|
|
76
55
|
expect(tags).toBe(tags2);
|
|
77
56
|
});
|
|
78
57
|
|
|
79
|
-
it('
|
|
80
|
-
// Create Story.
|
|
81
|
-
const story = new Story();
|
|
82
|
-
// Add passage.
|
|
83
|
-
story.addPassage(new Passage('A'));
|
|
84
|
-
// Add passage.
|
|
85
|
-
story.addPassage(new Passage('B'));
|
|
86
|
-
// Add StoryTitle
|
|
87
|
-
story.addPassage(new Passage('StoryTitle', 'Title'));
|
|
88
|
-
// Add Start
|
|
89
|
-
story.addPassage(new Passage('Start', 'Content'));
|
|
90
|
-
|
|
91
|
-
// Read StoryFormat.
|
|
92
|
-
const fr2 = readFileSync('test/StoryFormat/StoryFormatParser/format.js', 'utf-8');
|
|
93
|
-
|
|
94
|
-
// Parse StoryFormat.
|
|
95
|
-
const storyFormat = parseStoryFormat(fr2);
|
|
96
|
-
|
|
97
|
-
// Set start
|
|
98
|
-
story.start = 'Start';
|
|
99
|
-
|
|
100
|
-
// Write out HTML with story and storyFormat.
|
|
101
|
-
// (Will add position to passages without them.)
|
|
102
|
-
const fr3 = compileTwine2HTML(story, storyFormat);
|
|
103
|
-
|
|
104
|
-
// Parse new HTML file.
|
|
105
|
-
const story2 = parseTwine2HTML(fr3);
|
|
106
|
-
|
|
107
|
-
// Verify none of the directly created passages have position.
|
|
108
|
-
story.forEachPassage((passage) => {
|
|
109
|
-
expect(Object.prototype.hasOwnProperty.call(passage.metadata, 'position')).toBe(false);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
// Verify none parsed passages have position.
|
|
113
|
-
story2.forEachPassage((passage) => {
|
|
114
|
-
expect(Object.prototype.hasOwnProperty.call(passage.metadata, 'position')).toBe(false);
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("Don't write creator if missing originally", () => {
|
|
58
|
+
it('Throw error if IFID does not exist', () => {
|
|
119
59
|
// Create a new story.
|
|
120
60
|
const story = new Story();
|
|
121
61
|
|
|
122
62
|
// Create a passage.
|
|
123
63
|
story.addPassage(new Passage('A'));
|
|
124
64
|
|
|
125
|
-
// Create another passage.
|
|
126
|
-
story.addPassage(new Passage('B'));
|
|
127
|
-
|
|
128
|
-
// Create another passage.
|
|
129
|
-
story.addPassage(new Passage('StoryTitle', 'Title'));
|
|
130
|
-
|
|
131
|
-
// Add Start
|
|
132
|
-
story.addPassage(new Passage('Start', 'Content'));
|
|
133
|
-
|
|
134
|
-
// Set start
|
|
135
|
-
story.start = 'Start';
|
|
136
|
-
|
|
137
65
|
// Read StoryFormat.
|
|
138
|
-
const fr2 = readFileSync('test/
|
|
66
|
+
const fr2 = readFileSync('test/Twine2HTML/Twine2HTMLCompiler/format.js', 'utf-8');
|
|
139
67
|
|
|
140
68
|
// Parse StoryFormat.
|
|
141
69
|
const storyFormat = parseStoryFormat(fr2);
|
|
142
70
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// Parse HTML.
|
|
147
|
-
const story2 = parseTwine2HTML(fr3);
|
|
148
|
-
|
|
149
|
-
// Test creator (should be default)
|
|
150
|
-
expect(story.creator).toBe('extwee');
|
|
151
|
-
|
|
152
|
-
// Test parsed creator (should be default)
|
|
153
|
-
expect(story2.creator).toBe('extwee');
|
|
154
|
-
|
|
155
|
-
// Creator should be the same
|
|
156
|
-
expect(story.creator).toBe(story2.creator);
|
|
71
|
+
expect(() => {
|
|
72
|
+
compileTwine2HTML(story, storyFormat);
|
|
73
|
+
}).toThrow();
|
|
157
74
|
});
|
|
158
75
|
|
|
159
|
-
it('Throw error if
|
|
76
|
+
it('Throw error if starting passage property does not exist', () => {
|
|
160
77
|
// Create a new story.
|
|
161
78
|
const story = new Story();
|
|
162
79
|
|
|
163
80
|
// Create a passage.
|
|
164
81
|
story.addPassage(new Passage('A'));
|
|
165
82
|
|
|
83
|
+
// Create StoryTitle
|
|
84
|
+
story.addPassage(new Passage('StoryTitle', 'Name'));
|
|
85
|
+
|
|
86
|
+
// Set a passage that doesn't exist
|
|
87
|
+
story.start = 'Nope';
|
|
88
|
+
|
|
166
89
|
// Read StoryFormat.
|
|
167
|
-
const fr2 = readFileSync('test/
|
|
90
|
+
const fr2 = readFileSync('test/Twine2HTML/Twine2HTMLCompiler/format.js', 'utf-8');
|
|
168
91
|
|
|
169
92
|
// Parse StoryFormat.
|
|
170
93
|
const storyFormat = parseStoryFormat(fr2);
|
|
171
94
|
|
|
95
|
+
// Throws error.
|
|
172
96
|
expect(() => {
|
|
173
97
|
compileTwine2HTML(story, storyFormat);
|
|
174
98
|
}).toThrow();
|
|
175
99
|
});
|
|
176
100
|
|
|
177
|
-
it('Throw error if
|
|
101
|
+
it('Throw error if source is empty string in StoryFormat', () => {
|
|
178
102
|
// Create a new story.
|
|
179
103
|
const story = new Story();
|
|
180
104
|
|
|
181
|
-
// Create
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
// Create StoryTitle
|
|
185
|
-
story.addPassage(new Passage('StoryTitle', 'Name'));
|
|
186
|
-
|
|
187
|
-
// Read StoryFormat.
|
|
188
|
-
const fr2 = readFileSync('test/StoryFormat/StoryFormatParser/format.js', 'utf-8');
|
|
105
|
+
// Create StoryFormat.
|
|
106
|
+
const sf = new StoryFormat();
|
|
189
107
|
|
|
190
|
-
//
|
|
191
|
-
|
|
108
|
+
// Set source to empty string.
|
|
109
|
+
sf.source = '';
|
|
192
110
|
|
|
193
111
|
// Throws error.
|
|
194
112
|
expect(() => {
|
|
195
|
-
compileTwine2HTML(story,
|
|
113
|
+
compileTwine2HTML(story, sf);
|
|
196
114
|
}).toThrow();
|
|
197
115
|
});
|
|
198
116
|
|
|
199
|
-
it('Throw error if
|
|
117
|
+
it('Throw error if story name is empty string', () => {
|
|
200
118
|
// Create a new story.
|
|
201
119
|
const story = new Story();
|
|
202
120
|
|
|
203
|
-
// Create
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
// Create StoryTitle
|
|
207
|
-
story.addPassage(new Passage('StoryTitle', 'Name'));
|
|
121
|
+
// Create StoryFormat.
|
|
122
|
+
const sf = new StoryFormat();
|
|
208
123
|
|
|
209
|
-
// Set
|
|
210
|
-
|
|
124
|
+
// Set source to non-empty string.
|
|
125
|
+
sf.source = 'Test';
|
|
211
126
|
|
|
212
|
-
//
|
|
213
|
-
|
|
127
|
+
// Generate IFID (to avoid throwing error).
|
|
128
|
+
story.IFID = generateIFID();
|
|
214
129
|
|
|
215
|
-
//
|
|
216
|
-
|
|
130
|
+
// Set story name to empty string.
|
|
131
|
+
story.name = '';
|
|
217
132
|
|
|
218
133
|
// Throws error.
|
|
219
134
|
expect(() => {
|
|
220
|
-
compileTwine2HTML(story,
|
|
135
|
+
compileTwine2HTML(story, sf);
|
|
221
136
|
}).toThrow();
|
|
222
137
|
});
|
|
223
138
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { parse as parseTwine2HTML
|
|
2
|
+
import { parse as parseTwine2HTML } from '../../src/Twine2HTML/parse.js';
|
|
3
3
|
|
|
4
4
|
// Pull the name and version of this project from package.json.
|
|
5
5
|
// These are used as the 'creator' and 'creator-version'.
|
|
6
6
|
const { version } = JSON.parse(readFileSync('package.json', 'utf-8'));
|
|
7
7
|
|
|
8
8
|
describe('Twine2HTMLParser', () => {
|
|
9
|
-
describe('
|
|
9
|
+
describe('Errors', () => {
|
|
10
10
|
it('Should throw error if content is not a string', () => {
|
|
11
11
|
expect(() => { parseTwine2HTML({}); }).toThrow();
|
|
12
12
|
});
|
|
@@ -14,7 +14,9 @@ describe('Twine2HTMLParser', () => {
|
|
|
14
14
|
it('Should throw error if content is not Twine-2 style HTML', () => {
|
|
15
15
|
expect(() => { parseTwine2HTML(''); }).toThrow();
|
|
16
16
|
});
|
|
17
|
+
});
|
|
17
18
|
|
|
19
|
+
describe('#parse()', () => {
|
|
18
20
|
it('Should be able to parse Twine 2 HTML for story name', () => {
|
|
19
21
|
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/twineExample.html', 'utf-8');
|
|
20
22
|
const story = parseTwine2HTML(fr);
|
|
@@ -34,18 +36,6 @@ describe('Twine2HTMLParser', () => {
|
|
|
34
36
|
expect(p.tags).toHaveLength(2);
|
|
35
37
|
});
|
|
36
38
|
|
|
37
|
-
it('Should have default name', () => {
|
|
38
|
-
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingName.html', 'utf-8');
|
|
39
|
-
const story = parseTwine2HTML(fr);
|
|
40
|
-
expect(story.name).toBe('');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('Should set a missing IFID to an empty string', () => {
|
|
44
|
-
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingIFID.html', 'utf-8');
|
|
45
|
-
const tp = parseTwine2HTML(fr);
|
|
46
|
-
expect(tp.IFID).toBe('');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
39
|
it('Should have Extwee for creator when missing', () => {
|
|
50
40
|
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingCreator.html', 'utf-8');
|
|
51
41
|
const tp = parseTwine2HTML(fr);
|
|
@@ -73,7 +63,7 @@ describe('Twine2HTMLParser', () => {
|
|
|
73
63
|
it('Should have empty string as zoom when missing', () => {
|
|
74
64
|
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingZoom.html', 'utf-8');
|
|
75
65
|
const tp = parseTwine2HTML(fr);
|
|
76
|
-
expect(tp.zoom).toBe(
|
|
66
|
+
expect(tp.zoom).toBe(1);
|
|
77
67
|
});
|
|
78
68
|
|
|
79
69
|
it('Should not have position if passage does not', () => {
|
|
@@ -120,19 +110,10 @@ describe('Twine2HTMLParser', () => {
|
|
|
120
110
|
expect(stylesheetPassages.length).toBe(1);
|
|
121
111
|
});
|
|
122
112
|
|
|
123
|
-
it('Should
|
|
113
|
+
it('Should parse HTML without passage start node', () => {
|
|
124
114
|
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingStartnode.html', 'utf-8');
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
it('Should throw error if passage name is missing', () => {
|
|
129
|
-
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingPassageName.html', 'utf-8');
|
|
130
|
-
expect(() => { parseTwine2HTML(fr); }).toThrow();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('Should throw error without PID', () => {
|
|
134
|
-
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingPID.html', 'utf-8');
|
|
135
|
-
expect(() => { parseTwine2HTML(fr); }).toThrow();
|
|
115
|
+
const story = parseTwine2HTML(fr);
|
|
116
|
+
expect(story.start).toBe('');
|
|
136
117
|
});
|
|
137
118
|
|
|
138
119
|
it('Should parse tag colors', () => {
|
|
@@ -143,18 +124,6 @@ describe('Twine2HTMLParser', () => {
|
|
|
143
124
|
expect(tagColors.a).toBe('red');
|
|
144
125
|
});
|
|
145
126
|
|
|
146
|
-
it('Should throw error if startnode is missing', () => {
|
|
147
|
-
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/missingStartnode.html', 'utf-8');
|
|
148
|
-
expect(() => { parseTwine2HTML(fr); }).toThrow();
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('Should throw error when startnode has PID that does not exist', () => {
|
|
152
|
-
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/lyingStartnode.html', 'utf-8');
|
|
153
|
-
expect(() => {
|
|
154
|
-
parseTwine2HTML(fr);
|
|
155
|
-
}).toThrow();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
127
|
it('Do not update name and color if those attributes do not exist', () => {
|
|
159
128
|
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/lyingTagColors.html', 'utf-8');
|
|
160
129
|
const story = parseTwine2HTML(fr);
|
|
@@ -163,10 +132,61 @@ describe('Twine2HTMLParser', () => {
|
|
|
163
132
|
});
|
|
164
133
|
});
|
|
165
134
|
|
|
166
|
-
describe('
|
|
167
|
-
it('Should
|
|
168
|
-
|
|
169
|
-
|
|
135
|
+
describe('Unescaping', () => {
|
|
136
|
+
it('Should unescape HTML metacharacters for passage searching', () => {
|
|
137
|
+
const fr = readFileSync('test/Twine2HTML/Twine2HTMLParser/unescaping.html', 'utf-8');
|
|
138
|
+
const story = parseTwine2HTML(fr);
|
|
139
|
+
expect(story.getPassageByName('"Test"').text).toBe('Success');
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('Warnings', () => {
|
|
144
|
+
beforeEach(() => {
|
|
145
|
+
// Mock console.warn.
|
|
146
|
+
jest.spyOn(console, 'warn').mockImplementation();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
afterEach(() => {
|
|
150
|
+
// Restore all mocks.
|
|
151
|
+
jest.restoreAllMocks();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('Should generate a warning if name attribute is missing from tw-storydata', () => {
|
|
155
|
+
const s = '<tw-storydata ifid=\'E70FC479-01D9-4E44-AC6A-AFF9F5E1C475\'></tw-storydata>';
|
|
156
|
+
parseTwine2HTML(s);
|
|
157
|
+
expect(console.warn).toHaveBeenCalledWith('Warning: The name attribute is missing from tw-storydata!');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('Should generate a warning if ifid attribute is missing from tw-storydata', () => {
|
|
161
|
+
const s = '<tw-storydata name=\'Test\'></tw-storydata>';
|
|
162
|
+
parseTwine2HTML(s);
|
|
163
|
+
expect(console.warn).toHaveBeenCalledWith('Warning: The ifid attribute is missing from tw-storydata!');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('Should generate a warning if ifid on tw-storydata is malformed', () => {
|
|
167
|
+
const s = '<tw-storydata ifid=\'1234\'></tw-storydata>';
|
|
168
|
+
parseTwine2HTML(s);
|
|
169
|
+
expect(console.warn).toHaveBeenCalledWith('Warning: The IFID is not in valid UUIDv4 formatting on tw-storydata!');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('Should generate warning if passage name is missing', () => {
|
|
173
|
+
const fr = `<tw-storydata name="Tags" startnode="1" creator="Twine" creator-version="2.3.9" ifid="1A6023FC-F68A-4E55-BE9A-5EDFDB7879E6" zoom="1" format="Harlowe" format-version="3.1.0" options="" hidden>
|
|
174
|
+
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
175
|
+
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
176
|
+
<tw-passagedata pid="1" tags="this-one another-one-like-this" position="200,99" size="100,100">Double-click this passage to edit it.</tw-passagedata>
|
|
177
|
+
</tw-storydata>`;
|
|
178
|
+
parseTwine2HTML(fr);
|
|
179
|
+
expect(console.warn).toHaveBeenCalledWith('Warning: name attribute is missing! Default passage name will be used.');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('Should generate error if passage PID is missing', () => {
|
|
183
|
+
const fr = `<tw-storydata name="Tags" startnode="1" creator="Twine" creator-version="2.3.9" ifid="1A6023FC-F68A-4E55-BE9A-5EDFDB7879E6" zoom="1" format="Harlowe" format-version="3.1.0" options="" hidden>
|
|
184
|
+
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
185
|
+
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
186
|
+
<tw-passagedata name="Untitled Passage" tags="this-one another-one-like-this" position="200,99" size="100,100">Double-click this passage to edit it.</tw-passagedata>
|
|
187
|
+
</tw-storydata>`;
|
|
188
|
+
parseTwine2HTML(fr);
|
|
189
|
+
expect(console.warn).toHaveBeenCalledWith('Warning: pid attribute is missing! Default PID will be used.');
|
|
170
190
|
});
|
|
171
191
|
});
|
|
172
192
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
window.storyFormat({
|
|
2
|
+
"name": "Test Story Format",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"author": "Dan Cox",
|
|
5
|
+
"description": "A test story format.",
|
|
6
|
+
"source": "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>{{STORY_NAME}}</title><style>body { font-family: Arial, sans-serif; }</style></head><body>{{STORY_DATA}}</body></html>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"proofing": false
|
|
9
|
+
});
|
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
</head>
|
|
7
7
|
<body>
|
|
8
8
|
<tw-story></tw-story>
|
|
9
|
-
<tw-storydata name="Tags" startnode="1" creator="Twine" creator-version="2.3.9" ifid="1A6023FC-F68A-4E55-BE9A-5EDFDB7879E6 format="Harlowe" format-version="3.1.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript"></script><tw-passagedata pid="1" name="Untitled Passage" tags="this-one another-one-like-this" position="200,99" size="100,100">Double-click this passage to edit it.</tw-passagedata></tw-storydata>
|
|
9
|
+
<tw-storydata name="Tags" startnode="1" creator="Twine" creator-version="2.3.9" ifid="1A6023FC-F68A-4E55-BE9A-5EDFDB7879E6" format="Harlowe" format-version="3.1.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript"></script><tw-passagedata pid="1" name="Untitled Passage" tags="this-one another-one-like-this" position="200,99" size="100,100">Double-click this passage to edit it.</tw-passagedata></tw-storydata>
|
|
10
10
|
</body>
|
|
11
11
|
</html>
|