extwee 2.3.11 → 2.3.12
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/CHANGELOG.md +219 -0
- package/CONTRIBUTING.md +305 -0
- package/README.md +16 -0
- package/build/extwee.core.min.js +1 -1
- package/build/extwee.twine1html.min.js +1 -1
- package/build/extwee.twine2archive.min.js +1 -1
- package/build/extwee.tws.min.js +1 -1
- package/package.json +8 -5
- package/src/Story.js +2 -2
- package/types/src/Story.d.ts +1 -1
- package/.github/FUNDING.yml +0 -3
- package/.github/codeql-analysis.yml +0 -51
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/dependabot-automerge.yml +0 -23
- package/.github/workflows/nodejs.yml +0 -28
- package/.travis.yml +0 -13
- package/babel.config.json +0 -18
- package/docs/.nojekyll +0 -0
- package/docs/README.md +0 -224
- package/docs/_sidebar.md +0 -19
- package/docs/build/extwee.core.min.js +0 -1
- package/docs/build/extwee.twine1html.min.js +0 -1
- package/docs/build/extwee.twine2archive.min.js +0 -1
- package/docs/build/extwee.tws.min.js +0 -1
- package/docs/demos/compiler/extwee.core.min.js +0 -1
- package/docs/demos/compiler/index.css +0 -105
- package/docs/demos/compiler/index.html +0 -359
- package/docs/demos/decompile/extwee.core.min.js +0 -1
- package/docs/demos/decompile/index.css +0 -584
- package/docs/demos/decompile/index.html +0 -468
- package/docs/examples/dynamicPassages.md +0 -28
- package/docs/examples/jsonToTwee.md +0 -23
- package/docs/examples/twsToTwee.md +0 -25
- package/docs/formats/json.md +0 -17
- package/docs/formats/twee.md +0 -13
- package/docs/formats/twine1HTML.md +0 -13
- package/docs/formats/twine2ArchiveHTML.md +0 -13
- package/docs/formats/twine2HTML.md +0 -13
- package/docs/formats/tws.md +0 -9
- package/docs/index.html +0 -26
- package/docs/install/npm.md +0 -16
- package/docs/install/npx.md +0 -79
- package/docs/objects/passage.md +0 -47
- package/docs/objects/story.md +0 -69
- package/docs/objects/storyformat.md +0 -27
- package/eslint.config.js +0 -28
- package/extwee.config.json +0 -6
- package/extwee.config.md +0 -67
- package/jest.config.json +0 -5
- package/test/CLI/CLI.test.js +0 -49
- package/test/CLI/files/example.json +0 -1
- package/test/CLI/files/example6.twee +0 -22
- package/test/CLI/files/harlowe.js +0 -3
- package/test/CLI/files/input.html +0 -47
- package/test/CLI/files/output/test.twee +0 -0
- package/test/CLI/files/test.twee +0 -18
- package/test/CLI/files/tweeExample.twee +0 -17
- package/test/CLI/files/twine1/LICENSE.txt +0 -32
- package/test/CLI/files/twine1/code.js +0 -5
- package/test/CLI/files/twine1/engine.js +0 -43
- package/test/CLI/files/twine1/header.html +0 -325
- package/test/CLI/files/twine1Test.html +0 -371
- package/test/CLI/files/twineExample.html +0 -16
- package/test/Config/Config.test.js +0 -76
- package/test/Config/files/empty.json +0 -3
- package/test/Config/files/full.json +0 -8
- package/test/Config/files/invalid.json +0 -1
- package/test/Config/files/valid.json +0 -6
- package/test/Config/isDirectory.test.js +0 -50
- package/test/Config/isFile.test.js +0 -53
- package/test/Config/loadStoryFormat.test.js +0 -117
- package/test/Config/readDirectories.test.js +0 -78
- package/test/IFID/IFID.Generate.test.js +0 -10
- package/test/JSON/JSON.Parse.test.js +0 -316
- package/test/Objects/Passage.test.js +0 -274
- package/test/Objects/SnowmanCompatibility.test.js +0 -111
- package/test/Objects/Story.test.js +0 -1075
- package/test/Objects/StoryFormat.test.js +0 -219
- package/test/Roundtrip/Files/Example1.html +0 -64
- package/test/Roundtrip/Files/LICENSE +0 -19
- package/test/Roundtrip/Files/example1.twee +0 -10
- package/test/Roundtrip/Files/example2.twee +0 -27
- package/test/Roundtrip/Files/example4.twee +0 -27
- package/test/Roundtrip/Files/harlowe.js +0 -3
- package/test/Roundtrip/Files/round.html +0 -49
- package/test/Roundtrip/Roundtrip.test.js +0 -54
- package/test/StoryFormat/StoryFormat.Parse.test.js +0 -479
- package/test/TWS/Parse.test.js +0 -56
- package/test/TWS/TWSParser/Example5.tws +0 -414
- package/test/TWS/TWSParser/noscale.tws +0 -0
- package/test/TWS/TWSParser/nostory.tws +0 -0
- package/test/Twee/Twee.Escaping.test.js +0 -200
- package/test/Twee/Twee.Parse.test.js +0 -108
- package/test/Twee/TweeParser/cursed.twee +0 -16
- package/test/Twee/TweeParser/cycling.twee +0 -75
- package/test/Twee/TweeParser/emptytags.twee +0 -2
- package/test/Twee/TweeParser/example.twee +0 -32
- package/test/Twee/TweeParser/malformed.twee +0 -2
- package/test/Twee/TweeParser/missing.twee +0 -19
- package/test/Twee/TweeParser/multipleScriptPassages.twee +0 -19
- package/test/Twee/TweeParser/multipleStyleTag.twee +0 -19
- package/test/Twee/TweeParser/multipletags.twee +0 -10
- package/test/Twee/TweeParser/noTitle.twee +0 -2
- package/test/Twee/TweeParser/notes.twee +0 -16
- package/test/Twee/TweeParser/pasagemetadataerror.twee +0 -2
- package/test/Twee/TweeParser/scriptPassage.twee +0 -16
- package/test/Twee/TweeParser/singletag.twee +0 -13
- package/test/Twee/TweeParser/start.twee +0 -2
- package/test/Twee/TweeParser/startMetadata.twee +0 -14
- package/test/Twee/TweeParser/storydataerror.twee +0 -25
- package/test/Twee/TweeParser/style.twee +0 -16
- package/test/Twee/TweeParser/stylePassage.twee +0 -16
- package/test/Twee/TweeParser/test.twee +0 -25
- package/test/Twine1HTML/Twine1HTML.Compile.test.js +0 -180
- package/test/Twine1HTML/Twine1HTML.Parse.Web.test.js +0 -484
- package/test/Twine1HTML/Twine1HTML.Parse.test.js +0 -183
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/LICENSE +0 -674
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/engine.js +0 -43
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/jquery.js +0 -4
- package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/modernizr.js +0 -4
- package/test/Twine1HTML/Twine1HTMLCompiler/engineTest.html +0 -1
- package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/LICENSE +0 -32
- package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/code.js +0 -4
- package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/header.html +0 -327
- package/test/Twine1HTML/Twine1HTMLCompiler/test.html +0 -0
- package/test/Twine1HTML/Twine1HTMLCompiler/test1.html +0 -6
- package/test/Twine1HTML/Twine1HTMLCompiler/test2.html +0 -6
- package/test/Twine1HTML/Twine1HTMLCompiler/test3.html +0 -43
- package/test/Twine1HTML/Twine1HTMLCompiler/test4.html +0 -372
- package/test/Twine1HTML/Twine1HTMLCompiler/test5.html +0 -372
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Compile.test.js +0 -35
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.Web.test.js +0 -293
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.test.js +0 -42
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLCompiler/test1.html +0 -6
- package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLParser/test1.html +0 -3
- package/test/Twine2HTML/Twine2HTML.Compile.test.js +0 -139
- package/test/Twine2HTML/Twine2HTML.Parse.Web.test.js +0 -329
- package/test/Twine2HTML/Twine2HTML.Parse.test.js +0 -192
- package/test/Twine2HTML/Twine2HTMLCompiler/TestTags.html +0 -42
- package/test/Twine2HTML/Twine2HTMLCompiler/creator.html +0 -50
- package/test/Twine2HTML/Twine2HTMLCompiler/example6.twee +0 -16
- package/test/Twine2HTML/Twine2HTMLCompiler/format.js +0 -9
- package/test/Twine2HTML/Twine2HTMLCompiler/missingStoryTitle.twee +0 -29
- package/test/Twine2HTML/Twine2HTMLCompiler/test11.html +0 -121
- package/test/Twine2HTML/Twine2HTMLCompiler/test2.html +0 -58
- package/test/Twine2HTML/Twine2HTMLCompiler/test3.html +0 -49
- package/test/Twine2HTML/Twine2HTMLCompiler/test4.html +0 -50
- package/test/Twine2HTML/Twine2HTMLCompiler/test6.html +0 -49
- package/test/Twine2HTML/Twine2HTMLParser/Example1.html +0 -53
- package/test/Twine2HTML/Twine2HTMLParser/Tags.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/lyingStartnode.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/lyingTagColors.html +0 -48
- package/test/Twine2HTML/Twine2HTMLParser/missingCreator.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingCreatorVersion.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingFormat.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingFormatVersion.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingIFID.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingPassageTags.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/missingPosition.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/missingScript.html +0 -14
- package/test/Twine2HTML/Twine2HTMLParser/missingSize.html +0 -35
- package/test/Twine2HTML/Twine2HTMLParser/missingStartnode.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/missingStyle.html +0 -14
- package/test/Twine2HTML/Twine2HTMLParser/missingZoom.html +0 -11
- package/test/Twine2HTML/Twine2HTMLParser/tagColors.html +0 -31
- package/test/Twine2HTML/Twine2HTMLParser/twineExample.html +0 -23
- package/test/Twine2HTML/Twine2HTMLParser/twineExample2.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/twineExample3.html +0 -15
- package/test/Twine2HTML/Twine2HTMLParser/unescaping.html +0 -33
- package/test/Web/web-core-coverage.test.js +0 -175
- package/test/Web/web-core-global.test.js +0 -93
- package/test/Web/web-core.test.js +0 -156
- package/test/Web/web-exports.test.js +0 -136
- package/test/Web/web-twine1html.test.js +0 -105
- package/test/Web/web-twine2archive.test.js +0 -96
- package/test/Web/web-tws.test.js +0 -77
- package/test/Web/window.Extwee.test.js +0 -97
- package/tsconfig.json +0 -21
- package/webpack.config.js +0 -47
|
@@ -1,1075 +0,0 @@
|
|
|
1
|
-
import {jest} from '@jest/globals';
|
|
2
|
-
import { Story, creatorName, creatorVersion } from '../../src/Story.js';
|
|
3
|
-
import Passage from '../../src/Passage.js';
|
|
4
|
-
import { parse as parseTwee } from '../../src/Twee/parse.js';
|
|
5
|
-
import { readFileSync } from 'node:fs';
|
|
6
|
-
import { parse as HTMLParser } from 'node-html-parser';
|
|
7
|
-
import { generate as generateIFID } from '../../src/IFID/generate.js';
|
|
8
|
-
|
|
9
|
-
// Pull the name and version of this project from package.json.
|
|
10
|
-
// These are used as the 'creator' and 'creator-version'.
|
|
11
|
-
const { name, version } = JSON.parse(readFileSync('package.json'));
|
|
12
|
-
|
|
13
|
-
describe('Story', () => {
|
|
14
|
-
describe('constructor()', () => {
|
|
15
|
-
let s = null;
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
s = new Story();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('Should have extwee name', () => {
|
|
22
|
-
expect(s.creator).toBe(name);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('Should have extwee version', () => {
|
|
26
|
-
expect(s.creatorVersion).toBe(version);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('Should have name', () => {
|
|
30
|
-
s = new Story('Test');
|
|
31
|
-
expect(s.name).toBe('Test');
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('Should have default name', () => {
|
|
35
|
-
s = new Story();
|
|
36
|
-
expect(s.name).toBe('Untitled Story');
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
describe('creator', () => {
|
|
41
|
-
let s = null;
|
|
42
|
-
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
s = new Story();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('Set using String', () => {
|
|
48
|
-
s.creator = 'New';
|
|
49
|
-
expect(s.creator).toBe('New');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('Should throw error if not String', () => {
|
|
53
|
-
expect(() => {
|
|
54
|
-
s.creator = 1;
|
|
55
|
-
}).toThrow();
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('creatorVersion', () => {
|
|
60
|
-
let s = null;
|
|
61
|
-
|
|
62
|
-
beforeEach(() => {
|
|
63
|
-
s = new Story();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('Set using String', () => {
|
|
67
|
-
s.creatorVersion = 'New';
|
|
68
|
-
expect(s.creatorVersion).toBe('New');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('Should throw error if not String', () => {
|
|
72
|
-
expect(() => {
|
|
73
|
-
s.creatorVersion = 1;
|
|
74
|
-
}).toThrow();
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe('IFID', () => {
|
|
79
|
-
let s = null;
|
|
80
|
-
|
|
81
|
-
beforeEach(() => {
|
|
82
|
-
s = new Story();
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('Set using String', () => {
|
|
86
|
-
s.IFID = 'New';
|
|
87
|
-
expect(s.IFID).toBe('New');
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('Should throw error if not String', () => {
|
|
91
|
-
expect(() => {
|
|
92
|
-
s.IFID = 1;
|
|
93
|
-
}).toThrow();
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
describe('format', () => {
|
|
98
|
-
let s = null;
|
|
99
|
-
|
|
100
|
-
beforeEach(() => {
|
|
101
|
-
s = new Story();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('Set using String', () => {
|
|
105
|
-
s.format = 'New';
|
|
106
|
-
expect(s.format).toBe('New');
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('Should throw error if not String', () => {
|
|
110
|
-
expect(() => {
|
|
111
|
-
s.format = 1;
|
|
112
|
-
}).toThrow();
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe('formatVersion', () => {
|
|
117
|
-
let s = null;
|
|
118
|
-
|
|
119
|
-
beforeEach(() => {
|
|
120
|
-
s = new Story();
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('Set using String', () => {
|
|
124
|
-
s.formatVersion = '1.1.1';
|
|
125
|
-
expect(s.formatVersion).toBe('1.1.1');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('Should throw error if not String', () => {
|
|
129
|
-
expect(() => {
|
|
130
|
-
s.formatVersion = 1;
|
|
131
|
-
}).toThrow();
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
describe('name', () => {
|
|
136
|
-
let s = null;
|
|
137
|
-
|
|
138
|
-
beforeEach(() => {
|
|
139
|
-
s = new Story();
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('Set using String', () => {
|
|
143
|
-
s.name = 'New';
|
|
144
|
-
expect(s.name).toBe('New');
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it('Should throw error if not String', () => {
|
|
148
|
-
expect(() => {
|
|
149
|
-
s.name = 1;
|
|
150
|
-
}).toThrow();
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe('zoom', () => {
|
|
155
|
-
let s = null;
|
|
156
|
-
|
|
157
|
-
beforeEach(() => {
|
|
158
|
-
s = new Story();
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('Set using Number', () => {
|
|
162
|
-
s.zoom = 1.0;
|
|
163
|
-
expect(s.zoom).not.toBe(0);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('Should throw error if not String', () => {
|
|
167
|
-
expect(() => {
|
|
168
|
-
s.zoom = null;
|
|
169
|
-
}).toThrow();
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
describe('metadata', () => {
|
|
174
|
-
let s = null;
|
|
175
|
-
|
|
176
|
-
beforeEach(() => {
|
|
177
|
-
s = new Story();
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('Set metadata', () => {
|
|
181
|
-
s.metadata = {};
|
|
182
|
-
expect(s.metadata).not.toBe(null);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it('Should throw error if not object', () => {
|
|
186
|
-
expect(() => {
|
|
187
|
-
s.metadata = 1;
|
|
188
|
-
}).toThrow();
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('start', () => {
|
|
193
|
-
let s = null;
|
|
194
|
-
|
|
195
|
-
beforeEach(() => {
|
|
196
|
-
s = new Story();
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('Set start', () => {
|
|
200
|
-
s.start = 'Start';
|
|
201
|
-
expect(s.start).not.toBe('');
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it('Should throw error if not String', () => {
|
|
205
|
-
expect(() => {
|
|
206
|
-
s.start = 1;
|
|
207
|
-
}).toThrow();
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
describe('tagColors', () => {
|
|
212
|
-
let s = null;
|
|
213
|
-
|
|
214
|
-
beforeEach(() => {
|
|
215
|
-
s = new Story();
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('Set tagColors', () => {
|
|
219
|
-
s.tagColors = {
|
|
220
|
-
bar: 'green'
|
|
221
|
-
};
|
|
222
|
-
const count = Object.keys(s.tagColors).length;
|
|
223
|
-
expect(count).toBe(1);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('Should throw error if not object', () => {
|
|
227
|
-
expect(() => {
|
|
228
|
-
s.tagColors = null;
|
|
229
|
-
}).toThrow();
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
describe('storyStylesheet', () => {
|
|
234
|
-
let s = null;
|
|
235
|
-
|
|
236
|
-
beforeEach(() => {
|
|
237
|
-
s = new Story();
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it('Set storyStylesheet', () => {
|
|
241
|
-
s.storyStylesheet = 'Test';
|
|
242
|
-
expect(s.storyStylesheet).not.toBe('');
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it('Should throw error if not String', () => {
|
|
246
|
-
expect(() => {
|
|
247
|
-
s.storyStylesheet = 1;
|
|
248
|
-
}).toThrow();
|
|
249
|
-
}
|
|
250
|
-
);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
describe('storyJavaScript', () => {
|
|
254
|
-
let s = null;
|
|
255
|
-
|
|
256
|
-
beforeEach(() => {
|
|
257
|
-
s = new Story();
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it('Set storyJavaScript', () => {
|
|
261
|
-
s.storyJavaScript = 'Test';
|
|
262
|
-
expect(s.storyJavaScript).not.toBe('');
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it('Should throw error if not String', () => {
|
|
266
|
-
expect(() => {
|
|
267
|
-
s.storyJavaScript = 1;
|
|
268
|
-
}).toThrow();
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
describe('passages', () => {
|
|
273
|
-
let s = null;
|
|
274
|
-
|
|
275
|
-
beforeEach(() => {
|
|
276
|
-
s = new Story();
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it('Set passages to a new array containing at least one Passage', () => {
|
|
280
|
-
s.passages = [new Passage()];
|
|
281
|
-
expect(s.passages.length).toBe(1);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it('Should throw error if trying to set to a non-Array type', () => {
|
|
285
|
-
expect(() => {
|
|
286
|
-
s.passages = null;
|
|
287
|
-
}).toThrow();
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
it('Should throw error if trying to set to an array containing non-Passage types', () => {
|
|
291
|
-
expect(() => {
|
|
292
|
-
s.passages = [null];
|
|
293
|
-
}).toThrow();
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
describe('addPassage()', () => {
|
|
298
|
-
let s = null;
|
|
299
|
-
|
|
300
|
-
beforeEach(() => {
|
|
301
|
-
s = new Story();
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it('addPassage() - should increase size', () => {
|
|
305
|
-
const p = new Passage();
|
|
306
|
-
s.addPassage(p);
|
|
307
|
-
expect(s.size()).toBe(1);
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
it('addPassage() - should throw error if non-Passage', () => {
|
|
311
|
-
expect(() => {
|
|
312
|
-
s.addPassage(null);
|
|
313
|
-
}).toThrow();
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it('addPassage() - should override StoryData: ifid', function () {
|
|
317
|
-
// Generate object.
|
|
318
|
-
const o = {
|
|
319
|
-
ifid: 'D674C58C-DEFA-4F70-B7A2-27742230C0FC'
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
// Add the passage.
|
|
323
|
-
s.addPassage(new Passage('StoryData', JSON.stringify(o)));
|
|
324
|
-
|
|
325
|
-
// Test for IFID.
|
|
326
|
-
expect(s.IFID).toBe('D674C58C-DEFA-4F70-B7A2-27742230C0FC');
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it('addPassage() - should override StoryData: format', function () {
|
|
330
|
-
// Generate object.
|
|
331
|
-
const o = {
|
|
332
|
-
format: 'SugarCube'
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
// Add the passage.
|
|
336
|
-
s.addPassage(new Passage('StoryData', JSON.stringify(o)));
|
|
337
|
-
|
|
338
|
-
// Test for format.
|
|
339
|
-
expect(s.format).toBe('SugarCube');
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
it('addPassage() - should override StoryData: formatVersion', function () {
|
|
343
|
-
// Generate object.
|
|
344
|
-
const o = {
|
|
345
|
-
'format-version': '2.28.2'
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
// Add the passage.
|
|
349
|
-
s.addPassage(new Passage('StoryData', JSON.stringify(o)));
|
|
350
|
-
|
|
351
|
-
// Test for format.
|
|
352
|
-
expect(s.formatVersion).toBe('2.28.2');
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
it('addPassage() - should override StoryData: zoom', function () {
|
|
356
|
-
// Generate object.
|
|
357
|
-
const o = {
|
|
358
|
-
zoom: 0.5
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
// Add the passage.
|
|
362
|
-
s.addPassage(new Passage('StoryData', JSON.stringify(o)));
|
|
363
|
-
|
|
364
|
-
// Test for zoom.
|
|
365
|
-
expect(s.zoom).toBe(0.5);
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
it('addPassage() - should set start if Start passage and StoryData is not present', function () {
|
|
369
|
-
// Add the passage.
|
|
370
|
-
s.addPassage(new Passage('Start'));
|
|
371
|
-
|
|
372
|
-
// Test for start.
|
|
373
|
-
expect(s.start).toBe('Start');
|
|
374
|
-
});
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
describe('removePassageByName()', () => {
|
|
378
|
-
let s = null;
|
|
379
|
-
|
|
380
|
-
beforeEach(() => {
|
|
381
|
-
s = new Story();
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
it('removePassageByName() - should decrease size', () => {
|
|
385
|
-
s.addPassage(new Passage('Find'));
|
|
386
|
-
s.addPassage(new Passage('Find2'));
|
|
387
|
-
s.removePassageByName('Find');
|
|
388
|
-
expect(s.size()).toBe(1);
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
describe('getPassagesByTag()', () => {
|
|
393
|
-
let s = null;
|
|
394
|
-
|
|
395
|
-
beforeEach(() => {
|
|
396
|
-
s = new Story();
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
it('getPassagesByTag() - should find passages', () => {
|
|
400
|
-
const p = new Passage('Find', '', ['one']);
|
|
401
|
-
const p2 = new Passage('Find2', '', ['one']);
|
|
402
|
-
s.addPassage(p);
|
|
403
|
-
s.addPassage(p2);
|
|
404
|
-
const ps = s.getPassagesByTag('one');
|
|
405
|
-
expect(ps).toHaveLength(2);
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
it('getPassagesByTag() - should find none if none in collection', () => {
|
|
409
|
-
const ps = s.getPassagesByTag('one');
|
|
410
|
-
expect(ps).toHaveLength(0);
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
it('getPassagesByTag() - should find none if no tags match search', () => {
|
|
414
|
-
const p = new Passage('Find', '', ['one']);
|
|
415
|
-
const p2 = new Passage('Find2', '', ['one']);
|
|
416
|
-
s.addPassage(p);
|
|
417
|
-
s.addPassage(p2);
|
|
418
|
-
const ps = s.getPassagesByTag('two');
|
|
419
|
-
expect(ps).toHaveLength(0);
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
describe('getPassageByName()', () => {
|
|
424
|
-
let s = null;
|
|
425
|
-
|
|
426
|
-
beforeEach(() => {
|
|
427
|
-
s = new Story();
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
it('getPassageByName() - should get passage by name', () => {
|
|
431
|
-
const p = new Passage('Find');
|
|
432
|
-
s.addPassage(p);
|
|
433
|
-
const passage = s.getPassageByName('Find');
|
|
434
|
-
expect(passage.name).toBe('Find');
|
|
435
|
-
});
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
describe('size()', () => {
|
|
439
|
-
let s = null;
|
|
440
|
-
|
|
441
|
-
beforeEach(() => {
|
|
442
|
-
s = new Story();
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
it('size() - should report number of passages', () => {
|
|
446
|
-
// Create a Passage
|
|
447
|
-
const p = new Passage('');
|
|
448
|
-
// Test initial size
|
|
449
|
-
expect(s.size()).toBe(0);
|
|
450
|
-
// Add a passage
|
|
451
|
-
s.addPassage(p);
|
|
452
|
-
// Test size after adding one
|
|
453
|
-
expect(s.size()).toBe(1);
|
|
454
|
-
});
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
describe('toJSON()', function () {
|
|
458
|
-
it('Should have default Story values', function () {
|
|
459
|
-
// Create a new Story.
|
|
460
|
-
const s = new Story();
|
|
461
|
-
// Convert to string and then back to object.
|
|
462
|
-
const result = JSON.parse(s.toJSON());
|
|
463
|
-
expect(result.name).toBe('Untitled Story');
|
|
464
|
-
expect(Object.keys(result.tagColors).length).toBe(0);
|
|
465
|
-
expect(result.ifid).toBe('');
|
|
466
|
-
expect(result.start).toBe('');
|
|
467
|
-
expect(result.formatVersion).toBe('');
|
|
468
|
-
expect(result.format).toBe('');
|
|
469
|
-
expect(result.creator).toBe(creatorName);
|
|
470
|
-
expect(result.creatorVersion).toBe(creatorVersion);
|
|
471
|
-
expect(result.zoom).toBe(1);
|
|
472
|
-
expect(Object.keys(result.metadata).length).toBe(0);
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
it('Should have passage data', function () {
|
|
476
|
-
// Create default Story.
|
|
477
|
-
const s = new Story();
|
|
478
|
-
// Add a passage.
|
|
479
|
-
s.addPassage(new Passage('Example', 'Test'));
|
|
480
|
-
// Convert to JSON and then back to object.
|
|
481
|
-
const result = JSON.parse(s.toJSON());
|
|
482
|
-
// Should have a single passage.
|
|
483
|
-
expect(result.passages.length).toBe(1);
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
it('Should have style data', function () {
|
|
487
|
-
// Create default Story.
|
|
488
|
-
const s = new Story();
|
|
489
|
-
// Add a stylesheet.
|
|
490
|
-
s.storyStylesheet = 'Test';
|
|
491
|
-
// Convert to JSON and then back to object.
|
|
492
|
-
const result = JSON.parse(s.toJSON());
|
|
493
|
-
// Should have a stylesheet.
|
|
494
|
-
expect(result.style).toBe('Test');
|
|
495
|
-
}
|
|
496
|
-
);
|
|
497
|
-
|
|
498
|
-
it('Should have script data', function () {
|
|
499
|
-
// Create default Story.
|
|
500
|
-
const s = new Story();
|
|
501
|
-
// Add a script.
|
|
502
|
-
s.storyJavaScript = 'Test';
|
|
503
|
-
// Convert to JSON and then back to object.
|
|
504
|
-
const result = JSON.parse(s.toJSON());
|
|
505
|
-
// Should have a script.
|
|
506
|
-
expect(result.script).toBe('Test');
|
|
507
|
-
}
|
|
508
|
-
);
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
describe('toTwee()', function () {
|
|
512
|
-
let s = null;
|
|
513
|
-
|
|
514
|
-
beforeEach(() => {
|
|
515
|
-
s = new Story();
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
it('Should not generate format if empty', function () {
|
|
519
|
-
// Add one passage.
|
|
520
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
521
|
-
|
|
522
|
-
// Add an IFID (to prevent warning)
|
|
523
|
-
s.IFID = generateIFID();
|
|
524
|
-
|
|
525
|
-
// Set format to empty string.
|
|
526
|
-
s.format = '';
|
|
527
|
-
|
|
528
|
-
// Convert to Twee.
|
|
529
|
-
const t = s.toTwee();
|
|
530
|
-
|
|
531
|
-
// Test for format in metadata, should not exist.
|
|
532
|
-
expect(t.includes('"\'format":')).not.toBe(true);
|
|
533
|
-
});
|
|
534
|
-
|
|
535
|
-
it('Should not generate formatVersion if empty', function () {
|
|
536
|
-
// Add one passage.
|
|
537
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
538
|
-
|
|
539
|
-
// Add an IFID (to prevent warning)
|
|
540
|
-
s.IFID = generateIFID();
|
|
541
|
-
|
|
542
|
-
// Set formatVersion to empty string.
|
|
543
|
-
s.formatVersion = '';
|
|
544
|
-
|
|
545
|
-
// Convert to Twee.
|
|
546
|
-
const t = s.toTwee();
|
|
547
|
-
|
|
548
|
-
// Test for formatVersion in metadata, should not exist.
|
|
549
|
-
expect(t.includes('"\'format-version":')).not.toBe(true);
|
|
550
|
-
});
|
|
551
|
-
|
|
552
|
-
it('Should not generate zoom if zero', function () {
|
|
553
|
-
// Add one passage.
|
|
554
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
555
|
-
|
|
556
|
-
// Add an IFID (to prevent warning)
|
|
557
|
-
s.IFID = generateIFID();
|
|
558
|
-
|
|
559
|
-
// Set zoom to 0.
|
|
560
|
-
s.zoom = 0;
|
|
561
|
-
|
|
562
|
-
// Convert to Twee.
|
|
563
|
-
const t = s.toTwee();
|
|
564
|
-
|
|
565
|
-
// Test for zoom in metadata, should not exist.
|
|
566
|
-
expect(t.includes('"\'zoom":')).not.toBe(true);
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
it('Should not generate start if empty', function () {
|
|
570
|
-
// Add one passage.
|
|
571
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
572
|
-
|
|
573
|
-
// Add an IFID (to prevent warning)
|
|
574
|
-
s.IFID = generateIFID();
|
|
575
|
-
|
|
576
|
-
// Set start to empty string.
|
|
577
|
-
s.start = '';
|
|
578
|
-
|
|
579
|
-
// Convert to Twee.
|
|
580
|
-
const t = s.toTwee();
|
|
581
|
-
|
|
582
|
-
// Test for start in metadata, should not exist.
|
|
583
|
-
expect(t.includes('"\'start":')).not.toBe(true);
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
it('Should detect StoryTitle text', function () {
|
|
587
|
-
// Add one passage.
|
|
588
|
-
s.addPassage(new Passage('StoryTitle', 'Content'));
|
|
589
|
-
|
|
590
|
-
// Add an IFID (to prevent warning)
|
|
591
|
-
s.IFID = generateIFID();
|
|
592
|
-
|
|
593
|
-
// Convert to Twee.
|
|
594
|
-
const t = s.toTwee();
|
|
595
|
-
|
|
596
|
-
// Parse into a new story.
|
|
597
|
-
const story = parseTwee(t);
|
|
598
|
-
|
|
599
|
-
// Test for name.
|
|
600
|
-
expect(story.name).toBe('Content');
|
|
601
|
-
});
|
|
602
|
-
|
|
603
|
-
it('Should encode IFID', () => {
|
|
604
|
-
// Add passages.
|
|
605
|
-
s.addPassage(new Passage('Start'));
|
|
606
|
-
s.addPassage(new Passage('StoryTitle', 'Title'));
|
|
607
|
-
|
|
608
|
-
// Set an ifid property.
|
|
609
|
-
s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
|
|
610
|
-
|
|
611
|
-
// Convert to Twee.
|
|
612
|
-
const t = s.toTwee();
|
|
613
|
-
|
|
614
|
-
// Parse file.
|
|
615
|
-
const tp = parseTwee(t);
|
|
616
|
-
|
|
617
|
-
// Verify IFID.
|
|
618
|
-
expect(tp.IFID).toBe('DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A');
|
|
619
|
-
});
|
|
620
|
-
|
|
621
|
-
it('Should encode format, formatVersion, zoom, and start', () => {
|
|
622
|
-
// Add passages.
|
|
623
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
624
|
-
s.addPassage(new Passage('Untitled', 'Some stuff'));
|
|
625
|
-
|
|
626
|
-
s.name = 'Title';
|
|
627
|
-
s.format = 'Test';
|
|
628
|
-
s.formatVersion = '1.2.3';
|
|
629
|
-
s.zoom = 1;
|
|
630
|
-
s.start = 'Untitled';
|
|
631
|
-
s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
|
|
632
|
-
|
|
633
|
-
// Convert to Twee.
|
|
634
|
-
const t = s.toTwee();
|
|
635
|
-
|
|
636
|
-
// Parse Twee.
|
|
637
|
-
const story2 = parseTwee(t);
|
|
638
|
-
|
|
639
|
-
// Test for format, formatVersion, zoom, and start.
|
|
640
|
-
expect(story2.formatVersion).toBe('1.2.3');
|
|
641
|
-
expect(story2.format).toBe('Test');
|
|
642
|
-
expect(story2.zoom).toBe(1);
|
|
643
|
-
expect(story2.start).toBe('Untitled');
|
|
644
|
-
expect(story2.IFID).toBe('DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A');
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
it('Should write tag colors', () => {
|
|
648
|
-
// Add some passages.
|
|
649
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
650
|
-
s.addPassage(new Passage('Untitled', 'Some stuff'));
|
|
651
|
-
|
|
652
|
-
s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
|
|
653
|
-
|
|
654
|
-
// Add tag colors.
|
|
655
|
-
s.tagColors = {
|
|
656
|
-
bar: 'green',
|
|
657
|
-
foo: 'red',
|
|
658
|
-
qaz: 'blue'
|
|
659
|
-
};
|
|
660
|
-
|
|
661
|
-
// Convert to Twee.
|
|
662
|
-
const t = s.toTwee();
|
|
663
|
-
|
|
664
|
-
// Convert back into Story.
|
|
665
|
-
const story2 = parseTwee(t);
|
|
666
|
-
|
|
667
|
-
// Test for tag colors
|
|
668
|
-
expect(story2.tagColors.bar).toBe('green');
|
|
669
|
-
expect(story2.tagColors.foo).toBe('red');
|
|
670
|
-
expect(story2.tagColors.qaz).toBe('blue');
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
it('Should encode "script" tag', () => {
|
|
674
|
-
// Add passages.
|
|
675
|
-
s.addPassage(new Passage('Test', 'Test', ['script']));
|
|
676
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
677
|
-
|
|
678
|
-
// Set IFID.
|
|
679
|
-
s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
|
|
680
|
-
|
|
681
|
-
// Convert into Twee.
|
|
682
|
-
const t = s.toTwee();
|
|
683
|
-
|
|
684
|
-
// Convert back into Story.
|
|
685
|
-
const story = parseTwee(t);
|
|
686
|
-
|
|
687
|
-
// Script-tagged passages are now stored in storyJavaScript, not in passages array.
|
|
688
|
-
expect(story.storyJavaScript).toBe('Test');
|
|
689
|
-
});
|
|
690
|
-
|
|
691
|
-
it('Should encode "stylesheet" tag as storyStylesheet', () => {
|
|
692
|
-
// Add passages.
|
|
693
|
-
s.addPassage(new Passage('Test', 'Test', ['stylesheet']));
|
|
694
|
-
s.addPassage(new Passage('Start', 'Content'));
|
|
695
|
-
|
|
696
|
-
// Set IFID.
|
|
697
|
-
s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
|
|
698
|
-
|
|
699
|
-
// Convert into Twee.
|
|
700
|
-
const t = s.toTwee();
|
|
701
|
-
|
|
702
|
-
// Convert back into Story.
|
|
703
|
-
const story = parseTwee(t);
|
|
704
|
-
|
|
705
|
-
// Test for passage text.
|
|
706
|
-
expect(story.storyStylesheet).toBe('Test');
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
it('Should encode story stylesheet as passage with "stylesheet" tag', () => {
|
|
710
|
-
// Add passages.
|
|
711
|
-
s.storyStylesheet = 'Test';
|
|
712
|
-
|
|
713
|
-
// Set IFID.
|
|
714
|
-
s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
|
|
715
|
-
|
|
716
|
-
// Convert into Twee.
|
|
717
|
-
const t = s.toTwee();
|
|
718
|
-
|
|
719
|
-
// Convert back into Story.
|
|
720
|
-
const story = parseTwee(t);
|
|
721
|
-
|
|
722
|
-
// Test for passage text.
|
|
723
|
-
expect(story.storyStylesheet).toBe('Test');
|
|
724
|
-
}
|
|
725
|
-
);
|
|
726
|
-
|
|
727
|
-
it('Should encode story JavaScript as passage with "script" tag', () => {
|
|
728
|
-
// Add passages.
|
|
729
|
-
s.storyJavaScript = 'Test';
|
|
730
|
-
|
|
731
|
-
// Set IFID.
|
|
732
|
-
s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
|
|
733
|
-
|
|
734
|
-
// Convert into Twee.
|
|
735
|
-
const t = s.toTwee();
|
|
736
|
-
|
|
737
|
-
// Convert back into Story.
|
|
738
|
-
const story = parseTwee(t);
|
|
739
|
-
|
|
740
|
-
// Script-tagged passages are now stored in storyJavaScript, not in passages array.
|
|
741
|
-
expect(story.storyJavaScript).toBe('Test');
|
|
742
|
-
}
|
|
743
|
-
);
|
|
744
|
-
});
|
|
745
|
-
|
|
746
|
-
describe('toTwine2HTML()', () => {
|
|
747
|
-
let s = null;
|
|
748
|
-
|
|
749
|
-
beforeEach(() => {
|
|
750
|
-
s = new Story();
|
|
751
|
-
});
|
|
752
|
-
|
|
753
|
-
it('Should encode name', () => {
|
|
754
|
-
// Add passage.
|
|
755
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
756
|
-
// Set start.
|
|
757
|
-
s.start = 'Start';
|
|
758
|
-
// Set name.
|
|
759
|
-
s.name = 'Test';
|
|
760
|
-
// Create HTML.
|
|
761
|
-
const result = s.toTwine2HTML();
|
|
762
|
-
// Expect the name to be encoded.
|
|
763
|
-
expect(result.includes('<tw-storydata name="Test"')).toBe(true);
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
it('Should encode IFID', () => {
|
|
767
|
-
// Add passage.
|
|
768
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
769
|
-
// Set start.
|
|
770
|
-
s.start = 'Start';
|
|
771
|
-
// Set IFID.
|
|
772
|
-
s.IFID = 'B94AC8AD-03E3-4496-96C8-FE958645FE61';
|
|
773
|
-
// Create HTML.
|
|
774
|
-
const result = s.toTwine2HTML();
|
|
775
|
-
// Expect the IFID to be encoded.
|
|
776
|
-
expect(result.includes('ifid="B94AC8AD-03E3-4496-96C8-FE958645FE61"')).toBe(true);
|
|
777
|
-
});
|
|
778
|
-
|
|
779
|
-
it('Should encode stylesheet passages', () => {
|
|
780
|
-
// Add passage.
|
|
781
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
782
|
-
// Set start.
|
|
783
|
-
s.start = 'Start';
|
|
784
|
-
// Add a stylesheet passage.
|
|
785
|
-
s.addPassage(new Passage('Test', 'Word', ['stylesheet']));
|
|
786
|
-
// Create HTML.
|
|
787
|
-
const result = s.toTwine2HTML();
|
|
788
|
-
// Expect the stylesheet passage text to be encoded.
|
|
789
|
-
expect(result.includes('<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">Word')).toBe(true);
|
|
790
|
-
});
|
|
791
|
-
|
|
792
|
-
it('Should encode stylesheet property', () => {
|
|
793
|
-
// Add passage.
|
|
794
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
795
|
-
// Set start.
|
|
796
|
-
s.start = 'Start';
|
|
797
|
-
// Set stylesheet.
|
|
798
|
-
s.storyStylesheet = 'Test';
|
|
799
|
-
// Create HTML.
|
|
800
|
-
const result = s.toTwine2HTML();
|
|
801
|
-
// Expect the stylesheet passage text to be encoded.
|
|
802
|
-
expect(result.includes('<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">Test')).toBe(true);
|
|
803
|
-
});
|
|
804
|
-
|
|
805
|
-
it('Should encode script passages', () => {
|
|
806
|
-
// Add passage.
|
|
807
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
808
|
-
// Set start.
|
|
809
|
-
s.start = 'Start';
|
|
810
|
-
// Add a script passage.
|
|
811
|
-
s.addPassage(new Passage('Test', 'Word', ['script']));
|
|
812
|
-
// Create HTML.
|
|
813
|
-
const result = s.toTwine2HTML();
|
|
814
|
-
// Expect the script passage text to be encoded.
|
|
815
|
-
expect(result.includes('<script role="script" id="twine-user-script" type="text/twine-javascript">Word')).toBe(true);
|
|
816
|
-
});
|
|
817
|
-
|
|
818
|
-
it('Should encode script property', () => {
|
|
819
|
-
// Add passage.
|
|
820
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
821
|
-
// Set start.
|
|
822
|
-
s.start = 'Start';
|
|
823
|
-
// Set script.
|
|
824
|
-
s.storyJavaScript = 'Test';
|
|
825
|
-
// Create HTML.
|
|
826
|
-
const result = s.toTwine2HTML();
|
|
827
|
-
// Expect the script passage text to be encoded.
|
|
828
|
-
expect(result.includes('<script role="script" id="twine-user-script" type="text/twine-javascript">Test')).toBe(true);
|
|
829
|
-
});
|
|
830
|
-
|
|
831
|
-
it('Should encode format', () => {
|
|
832
|
-
// Add passage.
|
|
833
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
834
|
-
// Set start.
|
|
835
|
-
s.start = 'Start';
|
|
836
|
-
// Set format.
|
|
837
|
-
s.format = 'Harlowe';
|
|
838
|
-
// Create HTML.
|
|
839
|
-
const result = s.toTwine2HTML();
|
|
840
|
-
// Expect the format to be encoded.
|
|
841
|
-
expect(result.includes('format="Harlowe"')).toBe(true);
|
|
842
|
-
});
|
|
843
|
-
|
|
844
|
-
it('Should encode formatVersion', () => {
|
|
845
|
-
// Add passage.
|
|
846
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
847
|
-
// Set start.
|
|
848
|
-
s.start = 'Start';
|
|
849
|
-
// Set formatVersion.
|
|
850
|
-
s.formatVersion = '3.2.0';
|
|
851
|
-
// Create HTML.
|
|
852
|
-
const result = s.toTwine2HTML();
|
|
853
|
-
// Expect the formatVersion to be encoded.
|
|
854
|
-
expect(result.includes('format-version="3.2.0"')).toBe(true);
|
|
855
|
-
});
|
|
856
|
-
|
|
857
|
-
it('Should encode zoom', () => {
|
|
858
|
-
// Add passage.
|
|
859
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
860
|
-
// Set start.
|
|
861
|
-
s.start = 'Start';
|
|
862
|
-
// Set zoom.
|
|
863
|
-
s.zoom = 2;
|
|
864
|
-
// Create HTML.
|
|
865
|
-
const result = s.toTwine2HTML();
|
|
866
|
-
// Expect the zoom to be encoded.
|
|
867
|
-
expect(result.includes('zoom="2"')).toBe(true);
|
|
868
|
-
});
|
|
869
|
-
|
|
870
|
-
it('Should encode startnode as Start as single and only passage', () => {
|
|
871
|
-
// Add passage.
|
|
872
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
873
|
-
// Create HTML.
|
|
874
|
-
const result = s.toTwine2HTML();
|
|
875
|
-
// Expect the start to be encoded.
|
|
876
|
-
expect(result.includes('startnode="1"')).toBe(true);
|
|
877
|
-
});
|
|
878
|
-
|
|
879
|
-
it('Should encode startnode as 0 if no passages', () => {
|
|
880
|
-
// Create HTML.
|
|
881
|
-
const result = s.toTwine2HTML();
|
|
882
|
-
// Expect the start to be encoded.
|
|
883
|
-
expect(result.includes('startnode="0"')).toBe(true);
|
|
884
|
-
});
|
|
885
|
-
|
|
886
|
-
it('Should encode start if property is not set but Start passage is', () => {
|
|
887
|
-
// Add passage.
|
|
888
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
889
|
-
// Create HTML.
|
|
890
|
-
const result = s.toTwine2HTML();
|
|
891
|
-
// Expect the start to be encoded.
|
|
892
|
-
expect(result.includes('startnode="1"')).toBe(true);
|
|
893
|
-
});
|
|
894
|
-
|
|
895
|
-
it('Should encode creator', () => {
|
|
896
|
-
// Add passage.
|
|
897
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
898
|
-
// Set start.
|
|
899
|
-
s.start = 'Start';
|
|
900
|
-
// Create HTML.
|
|
901
|
-
const result = s.toTwine2HTML();
|
|
902
|
-
// Expect the creator to be encoded.
|
|
903
|
-
expect(result.includes(`creator="${creatorName}"`)).toBe(true);
|
|
904
|
-
});
|
|
905
|
-
|
|
906
|
-
it('Should encode creatorVersion', () => {
|
|
907
|
-
// Add passage.
|
|
908
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
909
|
-
// Set start.
|
|
910
|
-
s.start = 'Start';
|
|
911
|
-
// Create HTML.
|
|
912
|
-
const result = s.toTwine2HTML();
|
|
913
|
-
// Expect the creatorVersion to be encoded.
|
|
914
|
-
expect(result.includes(`creator-version="${creatorVersion}"`)).toBe(true);
|
|
915
|
-
});
|
|
916
|
-
|
|
917
|
-
it('Should not encode creatorVersion if not set', () => {
|
|
918
|
-
// Add passage.
|
|
919
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
920
|
-
// Set start.
|
|
921
|
-
s.start = 'Start';
|
|
922
|
-
// Set creatorVersion to empty string.
|
|
923
|
-
s.creatorVersion = '';
|
|
924
|
-
// Create HTML.
|
|
925
|
-
const result = s.toTwine2HTML();
|
|
926
|
-
// Expect the creatorVersion to be encoded.
|
|
927
|
-
expect(result.includes(`creator-version="${creatorVersion}"`)).not.toBe(true);
|
|
928
|
-
});
|
|
929
|
-
|
|
930
|
-
it('Should not encode creator if not set', () => {
|
|
931
|
-
// Add passage.
|
|
932
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
933
|
-
// Set start.
|
|
934
|
-
s.start = 'Start';
|
|
935
|
-
// Set creator to empty string.
|
|
936
|
-
s.creator = '';
|
|
937
|
-
// Create HTML.
|
|
938
|
-
const result = s.toTwine2HTML();
|
|
939
|
-
// Expect the creator to be encoded.
|
|
940
|
-
expect(result.includes(`creator="${creatorName}"`)).not.toBe(true);
|
|
941
|
-
});
|
|
942
|
-
|
|
943
|
-
it('Should not encode story tag colors if none are present', () => {
|
|
944
|
-
// Add passage.
|
|
945
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
946
|
-
// Set start.
|
|
947
|
-
s.start = 'Start';
|
|
948
|
-
// Create HTML.
|
|
949
|
-
const result = s.toTwine2HTML();
|
|
950
|
-
// Expect the tag colors to not be encoded if none are present.
|
|
951
|
-
expect(result.includes('<tw-tag')).toBe(false);
|
|
952
|
-
});
|
|
953
|
-
|
|
954
|
-
it('Should encode single story tag color', () => {
|
|
955
|
-
// Add passage.
|
|
956
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
957
|
-
// Set start.
|
|
958
|
-
s.start = 'Start';
|
|
959
|
-
// Add tag colors.
|
|
960
|
-
s.tagColors = {
|
|
961
|
-
bar: 'green'
|
|
962
|
-
};
|
|
963
|
-
// Create HTML.
|
|
964
|
-
const result = s.toTwine2HTML();
|
|
965
|
-
// Expect the tag colors to be encoded.
|
|
966
|
-
expect(result.includes('<tw-tag name="bar" color="green"></tw-tag>')).toBe(true);
|
|
967
|
-
});
|
|
968
|
-
|
|
969
|
-
it('Should encode multiple story tag colors', () => {
|
|
970
|
-
// Add passage.
|
|
971
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
972
|
-
// Set start.
|
|
973
|
-
s.start = 'Start';
|
|
974
|
-
// Add tag colors.
|
|
975
|
-
s.tagColors = {
|
|
976
|
-
bar: 'green',
|
|
977
|
-
foo: 'red'
|
|
978
|
-
};
|
|
979
|
-
// Create HTML.
|
|
980
|
-
const result = s.toTwine2HTML();
|
|
981
|
-
// Expect the tag colors to be encoded.
|
|
982
|
-
expect(result.includes('<tw-tag name="bar" color="green"></tw-tag>')).toBe(true);
|
|
983
|
-
expect(result.includes('<tw-tag name="foo" color="red"></tw-tag>')).toBe(true);
|
|
984
|
-
});
|
|
985
|
-
});
|
|
986
|
-
|
|
987
|
-
describe('toTwine1HTML()', function () {
|
|
988
|
-
let s = null;
|
|
989
|
-
|
|
990
|
-
beforeEach(() => {
|
|
991
|
-
s = new Story();
|
|
992
|
-
});
|
|
993
|
-
|
|
994
|
-
it('Should have correct data-size', function () {
|
|
995
|
-
// Add a passage.
|
|
996
|
-
s.addPassage(new Passage('Start', 'Word'));
|
|
997
|
-
// Create Twine 1 HTML.
|
|
998
|
-
const result = s.toTwine1HTML();
|
|
999
|
-
// Expect data-size to be 1.
|
|
1000
|
-
expect(result.includes('<div tiddler="Start"')).toBe(true);
|
|
1001
|
-
});
|
|
1002
|
-
});
|
|
1003
|
-
|
|
1004
|
-
describe('Escaping', function () {
|
|
1005
|
-
it('Should produce valid Twine 2 Story HTML', function () {
|
|
1006
|
-
// Create a new Story.
|
|
1007
|
-
const s = new Story('"Abuse" &test');
|
|
1008
|
-
// Add a passage.
|
|
1009
|
-
s.addPassage(new Passage('"Test"', 'Word'));
|
|
1010
|
-
// Set start.
|
|
1011
|
-
s.start = '"Test"';
|
|
1012
|
-
// Parse HTML.
|
|
1013
|
-
const root = HTMLParser(s.toTwine2HTML());
|
|
1014
|
-
// Expect correct name attribute for tw-storydata.
|
|
1015
|
-
expect(root.querySelector('tw-storydata').getAttribute('name')).toBe('"Abuse" &test');
|
|
1016
|
-
// Expect correct name attribute for tw-passagedata.
|
|
1017
|
-
expect(root.querySelector('tw-passagedata').getAttribute('name')).toBe('"Test"');
|
|
1018
|
-
// Use Twine 2 result.
|
|
1019
|
-
const s2 = '<tw-storydata name=""Abuse" &test" startnode="1" creator="Twine" creator-version="2.8.1" format="Harlowe" format-version="3.3.8" ifid="452A9D80-C759-42C5-B001-5B861A2410C5" options="" tags="" zoom="1" 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=""Test"" tags="&tag "bad"" position="300,100" size="100,100"></tw-passagedata></tw-storydata>';
|
|
1020
|
-
// Parse HTML.
|
|
1021
|
-
const root2 = HTMLParser(s2);
|
|
1022
|
-
// Expect correct name attribute for tw-storydata.
|
|
1023
|
-
expect(root2.querySelector('tw-storydata').getAttribute('name')).toBe('"Abuse" &test');
|
|
1024
|
-
// Expect correct name attribute for tw-passagedata.
|
|
1025
|
-
expect(root2.querySelector('tw-passagedata').getAttribute('name')).toBe('"Test"');
|
|
1026
|
-
});
|
|
1027
|
-
|
|
1028
|
-
it('Should produce valid Twine 1 Story HTML', function () {
|
|
1029
|
-
// Create a new Story.
|
|
1030
|
-
const s = new Story('"Abuse" &test');
|
|
1031
|
-
// Add a passage.
|
|
1032
|
-
s.addPassage(new Passage('"Test"', 'Word'));
|
|
1033
|
-
// Set start.
|
|
1034
|
-
s.start = '"Test"';
|
|
1035
|
-
// Parse HTML.
|
|
1036
|
-
const root = HTMLParser(s.toTwine1HTML());
|
|
1037
|
-
// Expect correct name attribute for div.
|
|
1038
|
-
expect(root.querySelector('div').getAttribute('tiddler')).toBe('"Test"');
|
|
1039
|
-
});
|
|
1040
|
-
});
|
|
1041
|
-
|
|
1042
|
-
describe('Warnings', function () {
|
|
1043
|
-
beforeEach(() => {
|
|
1044
|
-
// Mock console.warn.
|
|
1045
|
-
jest.spyOn(console, 'warn').mockImplementation();
|
|
1046
|
-
});
|
|
1047
|
-
|
|
1048
|
-
afterEach(() => {
|
|
1049
|
-
// Restore all mocks.
|
|
1050
|
-
jest.restoreAllMocks();
|
|
1051
|
-
});
|
|
1052
|
-
|
|
1053
|
-
it('Should generate warning if a passage with the same name already exists', function () {
|
|
1054
|
-
// Create a new Story.
|
|
1055
|
-
const s = new Story();
|
|
1056
|
-
// Add a passage.
|
|
1057
|
-
s.addPassage(new Passage('Test'));
|
|
1058
|
-
// Add a passage with the same name.
|
|
1059
|
-
s.addPassage(new Passage('Test'));
|
|
1060
|
-
// Expect warning.
|
|
1061
|
-
expect(console.warn).toHaveBeenCalledWith('Warning: A passage with the name "Test" already exists!');
|
|
1062
|
-
});
|
|
1063
|
-
|
|
1064
|
-
it('Should generate a warning if story IFID is not in the correct format', function () {
|
|
1065
|
-
// Create a new Story.
|
|
1066
|
-
const s = new Story();
|
|
1067
|
-
// Set IFID.
|
|
1068
|
-
s.IFID = 'Test';
|
|
1069
|
-
// Create Twee
|
|
1070
|
-
s.toTwee();
|
|
1071
|
-
// Expect warning.
|
|
1072
|
-
expect(console.warn).toHaveBeenCalledWith('Warning: IFID is not in UUIDv4 format! A new IFID was generated.');
|
|
1073
|
-
});
|
|
1074
|
-
});
|
|
1075
|
-
});
|