extwee 2.2.1 → 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/docs/objects/story.md +1 -2
- package/index.js +2 -0
- package/package.json +17 -17
- package/src/IFID/generate.js +20 -0
- package/src/JSON/parse.js +43 -0
- package/src/Passage.js +52 -3
- package/src/Story.js +266 -107
- package/src/StoryFormat/parse.js +190 -80
- package/src/StoryFormat.js +78 -88
- package/src/TWS/parse.js +2 -2
- package/src/Twee/parse.js +2 -3
- package/src/Twine1HTML/compile.js +2 -0
- package/src/Twine1HTML/parse.js +2 -3
- package/src/Twine2ArchiveHTML/compile.js +8 -0
- package/src/Twine2ArchiveHTML/parse.js +33 -3
- package/src/Twine2HTML/compile.js +31 -6
- package/src/Twine2HTML/parse.js +49 -54
- package/test/IFID/IFID.Generate.test.js +10 -0
- package/test/JSON/JSON.Parse.test.js +4 -4
- package/test/Story.test.js +256 -46
- 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/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.test.js +20 -4
- package/test/Twine2HTML/Twine2HTML.Compile.test.js +35 -120
- package/test/Twine2HTML/Twine2HTML.Parse.test.js +57 -38
- package/test/Twine2HTML/Twine2HTMLCompiler/format.js +9 -0
- package/test/Twine2HTML/Twine2HTMLParser/missingZoom.html +1 -1
- package/web-index.js +2 -0
- 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
|
@@ -2,8 +2,16 @@ import { Story } from '../Story.js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Write array of Story objects into Twine 2 Archive HTML.
|
|
5
|
+
* @see {@link https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-archive-spec.md Twine 2 Archive Specification}
|
|
6
|
+
* @function compile
|
|
5
7
|
* @param {Array} stories - Array of Story objects.
|
|
6
8
|
* @returns {string} Twine 2 Archive HTML.
|
|
9
|
+
* @example
|
|
10
|
+
* const story1 = new Story();
|
|
11
|
+
* const story2 = new Story();
|
|
12
|
+
* const stories = [story1, story2];
|
|
13
|
+
* console.log(compile(stories));
|
|
14
|
+
* // => '<tw-storydata name="Untitled" startnode="1" creator="Twine" creator-version="2.3.9" ifid="A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6" zoom="1" 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="" position="0,0" size="100,100"></tw-passagedata></tw-storydata>\n\n<tw-storydata name="Untitled" startnode="1" creator="Twine" creator-version="2.3.9" ifid="A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6" zoom="1" 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="" position="0,0" size="100,100"></tw-passagedata></tw-storydata>\n\n'
|
|
7
15
|
*/
|
|
8
16
|
function compile (stories) {
|
|
9
17
|
// Can only accept array.
|
|
@@ -2,9 +2,39 @@ import { parse as HtmlParser } from 'node-html-parser';
|
|
|
2
2
|
import { parse as parseTwine2HTML } from '../Twine2HTML/parse.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Parse
|
|
5
|
+
* Parse Twine 2 Archive HTML and returns an array of story objects.
|
|
6
|
+
* @see {@link https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-archive-spec.md Twine 2 Archive Specification}
|
|
7
|
+
* @function parse
|
|
6
8
|
* @param {string} content - Content to parse for Twine 2 HTML elements.
|
|
9
|
+
* @throws {TypeError} - Content is not a string!
|
|
7
10
|
* @returns {Array} Array of stories found in content.
|
|
11
|
+
* @example
|
|
12
|
+
* const content = '<tw-storydata name="Untitled" startnode="1" creator="Twine" creator-version="2.3.9" ifid="A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6" zoom="1" 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="" position="0,0" size="100,100"></tw-passagedata></tw-storydata>';
|
|
13
|
+
* console.log(parse(content));
|
|
14
|
+
* // => [
|
|
15
|
+
* // Story {
|
|
16
|
+
* // name: 'Untitled',
|
|
17
|
+
* // startnode: '1',
|
|
18
|
+
* // creator: 'Twine',
|
|
19
|
+
* // creatorVersion: '2.3.9',
|
|
20
|
+
* // ifid: 'A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6',
|
|
21
|
+
* // zoom: '1',
|
|
22
|
+
* // format: 'Harlowe',
|
|
23
|
+
* // formatVersion: '3.1.0',
|
|
24
|
+
* // options: '',
|
|
25
|
+
* // hidden: '',
|
|
26
|
+
* // passages: [
|
|
27
|
+
* // Passage {
|
|
28
|
+
* // pid: '1',
|
|
29
|
+
* // name: 'Untitled Passage',
|
|
30
|
+
* // tags: '',
|
|
31
|
+
* // position: '0,0',
|
|
32
|
+
* // size: '100,100',
|
|
33
|
+
* // text: ''
|
|
34
|
+
* // }
|
|
35
|
+
* // ]
|
|
36
|
+
* // }
|
|
37
|
+
* // ]
|
|
8
38
|
*/
|
|
9
39
|
function parse (content) {
|
|
10
40
|
// Can only parse string values.
|
|
@@ -32,8 +62,8 @@ function parse (content) {
|
|
|
32
62
|
|
|
33
63
|
// Did we find any elements?
|
|
34
64
|
if (storyDataElements.length === 0) {
|
|
35
|
-
//
|
|
36
|
-
|
|
65
|
+
// Produce a warning if no Twine 2 HTML content is found.
|
|
66
|
+
console.warn('Warning: No Twine 2 HTML content found!');
|
|
37
67
|
}
|
|
38
68
|
|
|
39
69
|
// Iterate through all `<tw-storydata>` elements.
|
|
@@ -3,20 +3,48 @@ import StoryFormat from '../StoryFormat.js';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Write a combination of Story + StoryFormat into Twine 2 HTML file.
|
|
6
|
+
* @see {@link https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md Twine 2 HTML Output Specification}
|
|
7
|
+
* @function compile
|
|
6
8
|
* @param {Story} story - Story object to write.
|
|
7
9
|
* @param {StoryFormat} storyFormat - StoryFormat to write.
|
|
8
|
-
* @returns {string} Twine 2 HTML.
|
|
10
|
+
* @returns {string} Twine 2 HTML based on StoryFormat and Story.
|
|
11
|
+
* @throws {Error} If story is not instance of Story.
|
|
12
|
+
* @throws {Error} If storyFormat is not instance of StoryFormat.
|
|
13
|
+
* @throws {Error} If storyFormat.source is empty string.
|
|
9
14
|
*/
|
|
10
15
|
function compile (story, storyFormat) {
|
|
16
|
+
// Check if story is instanceof Story.
|
|
11
17
|
if (!(story instanceof Story)) {
|
|
12
18
|
throw new Error('Error: story must be a Story object!');
|
|
13
19
|
}
|
|
14
20
|
|
|
21
|
+
// Check if storyFormat is instanceof StoryFormat.
|
|
15
22
|
if (!(storyFormat instanceof StoryFormat)) {
|
|
16
23
|
throw new Error('storyFormat must be a StoryFormat object!');
|
|
17
24
|
}
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
// Check if storyFormat.source is empty string.
|
|
27
|
+
if (storyFormat.source === '') {
|
|
28
|
+
throw new Error('StoryFormat source empty string!');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* There are two required attributes:
|
|
33
|
+
* - story.IFID: UUIDv4
|
|
34
|
+
* - story.name: string (non-empty)
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
// Check if story.IFID is UUIDv4 formatted.
|
|
38
|
+
if (story.IFID.match(/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[89ABab][0-9A-F]{3}-[0-9A-F]{12}$/) === null) {
|
|
39
|
+
throw new Error('Story IFID is invalid!');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check if story.name is empty string.
|
|
43
|
+
if (story.name === '') {
|
|
44
|
+
throw new Error('Story name empty string!');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Translate story to Twine 2 HTML.
|
|
20
48
|
const storyData = story.toTwine2HTML();
|
|
21
49
|
|
|
22
50
|
// Replace the story name in the source file.
|
|
@@ -25,11 +53,8 @@ function compile (story, storyFormat) {
|
|
|
25
53
|
// Replace the story data.
|
|
26
54
|
storyFormat.source = storyFormat.source.replaceAll(/{{STORY_DATA}}/gm, storyData);
|
|
27
55
|
|
|
28
|
-
// Combine everything together.
|
|
29
|
-
outputContents += storyFormat.source;
|
|
30
|
-
|
|
31
56
|
// Return content.
|
|
32
|
-
return
|
|
57
|
+
return storyFormat.source;
|
|
33
58
|
}
|
|
34
59
|
|
|
35
60
|
export { compile };
|
package/src/Twine2HTML/parse.js
CHANGED
|
@@ -8,8 +8,18 @@ import { decode } from 'html-entities';
|
|
|
8
8
|
*
|
|
9
9
|
* See: Twine 2 HTML Output Specification
|
|
10
10
|
* (https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md)
|
|
11
|
+
*
|
|
12
|
+
* Produces warnings for:
|
|
13
|
+
* - Missing name attribute on `<tw-storydata>` element.
|
|
14
|
+
* - Missing IFID attribute on `<tw-storydata>` element.
|
|
15
|
+
* - Malformed IFID attribute on `<tw-storydata>` element.
|
|
16
|
+
* @function parse
|
|
11
17
|
* @param {string} content - Twine 2 HTML content to parse.
|
|
12
|
-
* @returns {Story} Story
|
|
18
|
+
* @returns {Story} Story object based on Twine 2 HTML content.
|
|
19
|
+
* @throws {TypeError} Content is not a string.
|
|
20
|
+
* @throws {Error} Not Twine 2 HTML content!
|
|
21
|
+
* @throws {Error} Cannot parse passage data without name!
|
|
22
|
+
* @throws {Error} Passages are required to have PID!
|
|
13
23
|
*/
|
|
14
24
|
function parse (content) {
|
|
15
25
|
// Create new story.
|
|
@@ -17,7 +27,7 @@ function parse (content) {
|
|
|
17
27
|
|
|
18
28
|
// Can only parse string values.
|
|
19
29
|
if (typeof content !== 'string') {
|
|
20
|
-
throw new TypeError('Content is not a string!');
|
|
30
|
+
throw new TypeError('TypeError: Content is not a string!');
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
// Set default start node.
|
|
@@ -41,7 +51,7 @@ function parse (content) {
|
|
|
41
51
|
// Did we find any elements?
|
|
42
52
|
if (storyDataElements.length === 0) {
|
|
43
53
|
// If there is not a single `<tw-storydata>` element, this is not a Twine 2 story!
|
|
44
|
-
throw new
|
|
54
|
+
throw new TypeError('TypeError: Not Twine 2 HTML content!');
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
// We only parse the first element found.
|
|
@@ -56,7 +66,7 @@ function parse (content) {
|
|
|
56
66
|
story.name = storyData.attributes.name;
|
|
57
67
|
} else {
|
|
58
68
|
// Name is a required field. Warn user.
|
|
59
|
-
console.warn('
|
|
69
|
+
console.warn('Warning: The name attribute is missing from tw-storydata!');
|
|
60
70
|
}
|
|
61
71
|
|
|
62
72
|
/**
|
|
@@ -70,7 +80,13 @@ function parse (content) {
|
|
|
70
80
|
story.IFID = storyData.attributes.ifid;
|
|
71
81
|
} else {
|
|
72
82
|
// Name is a required filed. Warn user.
|
|
73
|
-
console.warn('
|
|
83
|
+
console.warn('Warning: The ifid attribute is missing from tw-storydata!');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Check if the IFID has valid formatting.
|
|
87
|
+
if (story.IFID.match(/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/) === null) {
|
|
88
|
+
// IFID is not valid.
|
|
89
|
+
console.warn('Warning: The IFID is not in valid UUIDv4 formatting on tw-storydata!');
|
|
74
90
|
}
|
|
75
91
|
|
|
76
92
|
/**
|
|
@@ -125,9 +141,6 @@ function parse (content) {
|
|
|
125
141
|
if (Object.prototype.hasOwnProperty.call(storyData.attributes, 'startnode')) {
|
|
126
142
|
// Take string value and convert to Int
|
|
127
143
|
startNode = Number.parseInt(storyData.attributes.startnode, 10);
|
|
128
|
-
} else {
|
|
129
|
-
// Throw error without start node.
|
|
130
|
-
throw new Error('Missing startnode in <tw-storydata>!');
|
|
131
144
|
}
|
|
132
145
|
|
|
133
146
|
// Pull out the `<tw-passagedata>` element.
|
|
@@ -173,15 +186,21 @@ function parse (content) {
|
|
|
173
186
|
* https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md#passages
|
|
174
187
|
*/
|
|
175
188
|
// Create a default value
|
|
176
|
-
let name =
|
|
189
|
+
let name = 'Untitled Passage';
|
|
177
190
|
// Does name exist?
|
|
178
191
|
if (Object.prototype.hasOwnProperty.call(attr, 'name')) {
|
|
179
192
|
// Escape the name
|
|
180
|
-
name =
|
|
193
|
+
name = attr.name;
|
|
181
194
|
} else {
|
|
182
|
-
|
|
195
|
+
console.warn('Warning: name attribute is missing! Default passage name will be used.');
|
|
183
196
|
}
|
|
184
197
|
|
|
198
|
+
/**
|
|
199
|
+
* tags: (string) Optional.
|
|
200
|
+
* A space-separated list of tags for the passage.
|
|
201
|
+
*
|
|
202
|
+
* https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md#passages
|
|
203
|
+
*/
|
|
185
204
|
// Create empty tag array.
|
|
186
205
|
let tags = [];
|
|
187
206
|
// Does the tags attribute exist?
|
|
@@ -190,7 +209,7 @@ function parse (content) {
|
|
|
190
209
|
// (Attributes can, themselves, be empty strings.)
|
|
191
210
|
if (attr.tags.length > 0 && attr.tags !== '""') {
|
|
192
211
|
// Escape the tags
|
|
193
|
-
tags =
|
|
212
|
+
tags = attr.tags;
|
|
194
213
|
// Split by spaces into an array
|
|
195
214
|
tags = tags.split(' ');
|
|
196
215
|
}
|
|
@@ -199,6 +218,12 @@ function parse (content) {
|
|
|
199
218
|
tags = tags.filter(tag => tag !== '');
|
|
200
219
|
}
|
|
201
220
|
|
|
221
|
+
/**
|
|
222
|
+
* metadata: (object) Optional.
|
|
223
|
+
* An object containing additional metadata about the passage.
|
|
224
|
+
*
|
|
225
|
+
* Twine 2 HTML does not support metadata, but other formats do.
|
|
226
|
+
*/
|
|
202
227
|
// Create metadata for passage.
|
|
203
228
|
const metadata = {};
|
|
204
229
|
|
|
@@ -222,14 +247,14 @@ function parse (content) {
|
|
|
222
247
|
* https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-htmloutput-spec.md#passages
|
|
223
248
|
*/
|
|
224
249
|
// Create a default PID
|
|
225
|
-
let pid =
|
|
250
|
+
let pid = 1;
|
|
226
251
|
// Does pid exist?
|
|
227
252
|
if (Object.prototype.hasOwnProperty.call(attr, 'pid')) {
|
|
228
253
|
// Parse string into int
|
|
229
254
|
// Update PID
|
|
230
255
|
pid = Number.parseInt(attr.pid, 10);
|
|
231
256
|
} else {
|
|
232
|
-
console.warn('
|
|
257
|
+
console.warn('Warning: pid attribute is missing! Default PID will be used.');
|
|
233
258
|
}
|
|
234
259
|
|
|
235
260
|
// Check the current PID against startNode number.
|
|
@@ -239,24 +264,15 @@ function parse (content) {
|
|
|
239
264
|
story.start = name;
|
|
240
265
|
}
|
|
241
266
|
|
|
242
|
-
//
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
metadata
|
|
252
|
-
)
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// There was an invalid startNode.
|
|
258
|
-
if (story.start === '') {
|
|
259
|
-
throw new Error('startNode does not exist within passages!');
|
|
267
|
+
// Add a new Passage into an array
|
|
268
|
+
story.addPassage(
|
|
269
|
+
new Passage(
|
|
270
|
+
decode(name),
|
|
271
|
+
decode(text),
|
|
272
|
+
tags.map(tag => decode(tag)),
|
|
273
|
+
metadata
|
|
274
|
+
)
|
|
275
|
+
);
|
|
260
276
|
}
|
|
261
277
|
|
|
262
278
|
// Look for the style element
|
|
@@ -325,25 +341,4 @@ function parse (content) {
|
|
|
325
341
|
return story;
|
|
326
342
|
}
|
|
327
343
|
|
|
328
|
-
|
|
329
|
-
* Try to escape Twine 2 meta-characters.
|
|
330
|
-
* @param {string} result - Text to parse.
|
|
331
|
-
* @returns {string} Escaped characters.
|
|
332
|
-
*/
|
|
333
|
-
function escapeMetacharacters (result) {
|
|
334
|
-
// Replace any single backslash, \, with two of them, \\.
|
|
335
|
-
result = result.replace(/\\/g, '\\');
|
|
336
|
-
// Double-escape escaped {
|
|
337
|
-
result = result.replace(/\\\{/g, '\\\\{');
|
|
338
|
-
// Double-escape escaped }
|
|
339
|
-
result = result.replace(/\\\}/g, '\\\\}');
|
|
340
|
-
// Double-escape escaped [
|
|
341
|
-
result = result.replace(/\\\[/g, '\\\\[');
|
|
342
|
-
// Double-escape escaped ]
|
|
343
|
-
result = result.replace(/\\\]/g, '\\\\]');
|
|
344
|
-
|
|
345
|
-
return result;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
export { parse, escapeMetacharacters };
|
|
349
|
-
export default parse;
|
|
344
|
+
export { parse };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { generate } from '../../src/IFID/generate.js';
|
|
2
|
+
|
|
3
|
+
describe('src/IFID/generate.js', () => {
|
|
4
|
+
describe('generate()', () => {
|
|
5
|
+
it('should generate a valid IFID', () => {
|
|
6
|
+
const ifid = generate();
|
|
7
|
+
expect(ifid).toMatch(/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -16,7 +16,7 @@ describe('JSON', () => {
|
|
|
16
16
|
const s = parseJSON(r.toJSON());
|
|
17
17
|
|
|
18
18
|
// Check all properties.
|
|
19
|
-
expect(s.name).toBe('');
|
|
19
|
+
expect(s.name).toBe('Untitled Story');
|
|
20
20
|
expect(Object.keys(s.tagColors).length).toBe(0);
|
|
21
21
|
expect(s.IFID).toBe('');
|
|
22
22
|
expect(s.start).toBe('');
|
|
@@ -24,7 +24,7 @@ describe('JSON', () => {
|
|
|
24
24
|
expect(s.format).toBe('');
|
|
25
25
|
expect(s.creator).toBe(creatorName);
|
|
26
26
|
expect(s.creatorVersion).toBe(creatorVersion);
|
|
27
|
-
expect(s.zoom).toBe(
|
|
27
|
+
expect(s.zoom).toBe(1);
|
|
28
28
|
expect(Object.keys(s.metadata).length).toBe(0);
|
|
29
29
|
});
|
|
30
30
|
|
|
@@ -52,7 +52,7 @@ describe('JSON', () => {
|
|
|
52
52
|
it('Should parse everything but name', function () {
|
|
53
53
|
const s = '{"tagColors":{"r":"red"},"ifid":"dd","start":"Start","formatVersion":"1.0","metadata":{"some":"thing"},"format":"Snowman","creator":"extwee","creatorVersion":"2.2.0","zoom":1,"passages":[{"name":"Start","tags":["tag1"],"metadata":{},"text":"Word"}]}';
|
|
54
54
|
const r = parseJSON(s);
|
|
55
|
-
expect(r.name).toBe('');
|
|
55
|
+
expect(r.name).toBe('Untitled Story');
|
|
56
56
|
expect(Object.keys(r.tagColors).length).toBe(1);
|
|
57
57
|
expect(r.IFID).toBe('DD');
|
|
58
58
|
expect(r.start).toBe('Start');
|
|
@@ -189,7 +189,7 @@ describe('JSON', () => {
|
|
|
189
189
|
expect(r.format).toBe('Snowman');
|
|
190
190
|
expect(r.creator).toBe(creatorName);
|
|
191
191
|
expect(r.creatorVersion).toBe('2.2.0');
|
|
192
|
-
expect(r.zoom).toBe(
|
|
192
|
+
expect(r.zoom).toBe(1);
|
|
193
193
|
expect(r.size()).toBe(1);
|
|
194
194
|
});
|
|
195
195
|
|