extwee 2.0.0 → 2.0.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/bin/extwee.js +1 -1
- package/package.json +2 -3
- package/src/HTMLWriter.js +33 -2
- package/src/Story.js +1 -1
- package/src/TweeParser.js +2 -7
- package/test/CLI/test2.html +1 -1
- package/test/HTMLWriter/creator.html +1 -1
- package/test/HTMLWriter/test11.html +1 -1
- package/test/HTMLWriter/test4.html +1 -1
- package/test/HTMLWriter/test6.html +1 -1
- package/test/HTMLWriter.test.js +24 -14
- package/test/Passage.test.js +22 -22
- package/test/Roundtrip/round.html +1 -1
- package/test/TweeParser.test.js +14 -14
- package/test/TweeWriter/test1.twee +1 -1
- package/test/TweeWriter/test5.twee +1 -1
- package/test/TweeWriter.test.js +15 -12
package/bin/extwee.js
CHANGED
|
@@ -14,7 +14,7 @@ import { Command } from 'commander';
|
|
|
14
14
|
const program = new Command();
|
|
15
15
|
|
|
16
16
|
program
|
|
17
|
-
.version('2.0.
|
|
17
|
+
.version('2.0.2')
|
|
18
18
|
.option('-c', 'From Twee into HTML')
|
|
19
19
|
.option('-d', 'From HTML into Twee')
|
|
20
20
|
.option('-s <storyformat>', 'Path to storyformat')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "extwee",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "A Twee 3 compiler written in JS.",
|
|
5
5
|
"author": "Dan Cox",
|
|
6
6
|
"main": "index.js",
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
"extwee": "bin/extwee.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "jest --
|
|
12
|
-
"test:watch": "jest --watch",
|
|
11
|
+
"test": "jest --runInBand --coverage --colors",
|
|
13
12
|
"lint": "eslint ./src/**/*.js --fix",
|
|
14
13
|
"lint:test": "eslint ./test/*.test.js --fix",
|
|
15
14
|
"all": "npm run lint && npm run lint:test && npm run test"
|
package/src/HTMLWriter.js
CHANGED
|
@@ -171,13 +171,13 @@ export default class HTMLWriter {
|
|
|
171
171
|
storyData += `size="${passage.metadata.size}" `;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
storyData += `>${passage.text}</tw-passagedata>\n`;
|
|
174
|
+
storyData += `>${HTMLWriter.escape(passage.text)}</tw-passagedata>\n`;
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
storyData += '</tw-storydata>';
|
|
178
178
|
|
|
179
179
|
// Replace the story name in the source file
|
|
180
|
-
storyFormat.source = storyFormat.source.
|
|
180
|
+
storyFormat.source = storyFormat.source.replaceAll(/{{STORY_NAME}}/g, story.name);
|
|
181
181
|
|
|
182
182
|
// Replace the story data
|
|
183
183
|
storyFormat.source = storyFormat.source.replace('{{STORY_DATA}}', storyData);
|
|
@@ -193,4 +193,35 @@ export default class HTMLWriter {
|
|
|
193
193
|
throw new Error('Error: Cannot write HTML file!');
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Escape HTML characters
|
|
199
|
+
*
|
|
200
|
+
* @public
|
|
201
|
+
* @static
|
|
202
|
+
* @function escape
|
|
203
|
+
* @param {string} text - Text to escape
|
|
204
|
+
* @returns {string} Escaped text
|
|
205
|
+
*/
|
|
206
|
+
static escape (text) {
|
|
207
|
+
// Throw error if text is not a string
|
|
208
|
+
if (Object.prototype.toString.call(text) !== '[object String]') {
|
|
209
|
+
throw new Error('Text argument is not a String');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const rules = [
|
|
213
|
+
['&', '&'],
|
|
214
|
+
['<', '<'],
|
|
215
|
+
['>', '>'],
|
|
216
|
+
['"', '"'],
|
|
217
|
+
["'", '''],
|
|
218
|
+
['`', '`']
|
|
219
|
+
];
|
|
220
|
+
|
|
221
|
+
rules.forEach(([rule, template]) => {
|
|
222
|
+
text = text.replaceAll(rule, template);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
return text;
|
|
226
|
+
}
|
|
196
227
|
}
|
package/src/Story.js
CHANGED
package/src/TweeParser.js
CHANGED
|
@@ -18,13 +18,8 @@ export default class TweeParser {
|
|
|
18
18
|
// Create Story.
|
|
19
19
|
const story = new Story();
|
|
20
20
|
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
return Object.prototype.toString.call(x) === '[object String]';
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Throw error if fileContents is empty
|
|
27
|
-
if (!isString(fileContents)) {
|
|
21
|
+
// Throw error if fileContents is not a string
|
|
22
|
+
if (Object.prototype.toString.call(fileContents) !== '[object String]') {
|
|
28
23
|
throw new Error('Contents not a String');
|
|
29
24
|
}
|
|
30
25
|
|
package/test/CLI/test2.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
<tw-story></tw-story>
|
|
13
13
|
|
|
14
|
-
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.
|
|
14
|
+
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.2" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="0" format="Harlowe" format-version="3.0.2" options hidden>
|
|
15
15
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">body {background-color: green;}</style>
|
|
16
16
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
17
17
|
<tw-passagedata pid="1" name="StoryTitle">twineExample</tw-passagedata>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.
|
|
12
|
+
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.2" ifid="B59351FF-AED5-4491-9295-E544AD96B578" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
15
|
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
|
@@ -100,7 +100,7 @@ var saveAs=saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||f
|
|
|
100
100
|
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
|
101
101
|
<div id="init-loading"><div>Loading…</div></div>
|
|
102
102
|
</div>
|
|
103
|
-
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.
|
|
103
|
+
<tw-storydata name="twineExample" startnode="2" creator="extwee" creator-version="2.0.2" ifid="2B68ECD6-348F-4CF5-96F8-549A512A8128" zoom="0" format="SugarCube" format-version="2.31.1" options hidden>
|
|
104
104
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">body {background-color: green;}</style>
|
|
105
105
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
106
106
|
<tw-passagedata pid="1" name="StoryTitle">twineExample</tw-passagedata>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.
|
|
12
|
+
<tw-storydata name="Title" startnode="4" creator="extwee" creator-version="2.0.2" ifid="A2148F0D-A7D6-4EE2-B0A1-CC10B1D17E1A" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
15
|
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<tw-story tags></tw-story>
|
|
12
|
-
<tw-storydata name="Name" startnode="3" creator="extwee" creator-version="2.0.
|
|
12
|
+
<tw-storydata name="Name" startnode="3" creator="extwee" creator-version="2.0.2" ifid="5BA15E42-9C1D-4B9A-839E-7B8E294947A5" zoom="0" format="Snowman" format-version="2.0.0" options hidden>
|
|
13
13
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
14
14
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
15
15
|
<tw-passagedata pid="1" name="A"></tw-passagedata>
|
package/test/HTMLWriter.test.js
CHANGED
|
@@ -6,18 +6,18 @@ import HTMLWriter from '../src/HTMLWriter.js';
|
|
|
6
6
|
import Story from '../src/Story.js';
|
|
7
7
|
import Passage from '../src/Passage.js';
|
|
8
8
|
|
|
9
|
-
describe('HTMLWriter',
|
|
10
|
-
describe('#write()',
|
|
11
|
-
|
|
9
|
+
describe('HTMLWriter', () => {
|
|
10
|
+
describe('#write()', () => {
|
|
11
|
+
it('story should be instanceof Story', () => {
|
|
12
12
|
expect(() => { HTMLWriter.write('test/HTMLWriter/test.html', {}); }).toThrow();
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
it('storyFormat should be instanceof StoryFormat', () => {
|
|
16
16
|
const s = new Story();
|
|
17
17
|
expect(() => { HTMLWriter.write('test/HTMLWriter/test.html', s, {}); }).toThrow();
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
it('Read, write, and read HTML', () => {
|
|
21
21
|
// Read HTML.
|
|
22
22
|
const fr = FileReader.read('test/HTMLParser/twineExample3.html');
|
|
23
23
|
// Parse HTML.
|
|
@@ -44,7 +44,7 @@ describe('HTMLWriter', function () {
|
|
|
44
44
|
expect(s1Title).toBe(s2Title);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
it('Should write one and two-tag passages', () => {
|
|
48
48
|
// Read HTML.
|
|
49
49
|
const fr = FileReader.read('test/HTMLWriter/TestTags.html');
|
|
50
50
|
// Parse HTML.
|
|
@@ -81,7 +81,7 @@ describe('HTMLWriter', function () {
|
|
|
81
81
|
expect(tags).toBe(tags2);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
it('Should throw error if file path invalid', () => {
|
|
85
85
|
// Read HTML.
|
|
86
86
|
const fr = FileReader.read('test/HTMLParser/twineExample3.html');
|
|
87
87
|
// Parse HTML.
|
|
@@ -98,7 +98,7 @@ describe('HTMLWriter', function () {
|
|
|
98
98
|
}).toThrow();
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
it('Should not add optional position to passages', () => {
|
|
102
102
|
// Create Story.
|
|
103
103
|
const story = new Story();
|
|
104
104
|
// Add passage.
|
|
@@ -135,7 +135,7 @@ describe('HTMLWriter', function () {
|
|
|
135
135
|
});
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
it("Don't write creator if missing originally", () => {
|
|
139
139
|
// Create a new story.
|
|
140
140
|
const story = new Story();
|
|
141
141
|
|
|
@@ -174,7 +174,7 @@ describe('HTMLWriter', function () {
|
|
|
174
174
|
expect(story.creator).toBe(story2.creator);
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
it('Throw error if StoryTitle does not exist', () => {
|
|
178
178
|
// Create a new story.
|
|
179
179
|
const story = new Story();
|
|
180
180
|
|
|
@@ -191,7 +191,7 @@ describe('HTMLWriter', function () {
|
|
|
191
191
|
}).toThrow();
|
|
192
192
|
});
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
it('Throw error if no start or Start exists', () => {
|
|
195
195
|
// Create a new story.
|
|
196
196
|
const story = new Story();
|
|
197
197
|
|
|
@@ -212,7 +212,7 @@ describe('HTMLWriter', function () {
|
|
|
212
212
|
}).toThrow();
|
|
213
213
|
});
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
it('Write with Start without start', () => {
|
|
216
216
|
// Create a new story.
|
|
217
217
|
const story = new Story();
|
|
218
218
|
|
|
@@ -242,7 +242,7 @@ describe('HTMLWriter', function () {
|
|
|
242
242
|
expect(story2.start).toBe('Start');
|
|
243
243
|
});
|
|
244
244
|
|
|
245
|
-
|
|
245
|
+
it('Throw error if starting passage property does not exist', () => {
|
|
246
246
|
// Create a new story.
|
|
247
247
|
const story = new Story();
|
|
248
248
|
|
|
@@ -266,7 +266,7 @@ describe('HTMLWriter', function () {
|
|
|
266
266
|
}).toThrow();
|
|
267
267
|
});
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
it('Should correctly replace all instances of STORY_NAME', () => {
|
|
270
270
|
const fr = FileReader.read('test/HTMLWriter/example6.twee');
|
|
271
271
|
const story = TweeParser.parse(fr);
|
|
272
272
|
const storyFormatFile = FileReader.read('test/StoryFormatParser/format_doublename.js');
|
|
@@ -276,4 +276,14 @@ describe('HTMLWriter', function () {
|
|
|
276
276
|
expect(frh.indexOf('STORY_NAME')).toBe(-1);
|
|
277
277
|
});
|
|
278
278
|
});
|
|
279
|
+
|
|
280
|
+
describe('escape()', () => {
|
|
281
|
+
it('Should throw error if argument is not string', () => {
|
|
282
|
+
expect(() => { HTMLWriter.escape(1); }).toThrow();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('Should escape HTML sequences', () => {
|
|
286
|
+
expect(HTMLWriter.escape('<script>alert("Hi!");</script>')).toBe('<script>alert("Hi!");</script>');
|
|
287
|
+
});
|
|
288
|
+
});
|
|
279
289
|
});
|
package/test/Passage.test.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Passage from '../src/Passage.js';
|
|
2
2
|
|
|
3
|
-
describe('Passage',
|
|
4
|
-
describe('#constructor()',
|
|
5
|
-
test('Set default values',
|
|
3
|
+
describe('Passage', () => {
|
|
4
|
+
describe('#constructor()', () => {
|
|
5
|
+
test('Set default values', () => {
|
|
6
6
|
const p = new Passage();
|
|
7
7
|
expect(p.name).toBe('');
|
|
8
8
|
expect(p.tags).toHaveLength(0);
|
|
@@ -12,14 +12,14 @@ describe('Passage', function () {
|
|
|
12
12
|
});
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
describe('name',
|
|
16
|
-
test('Set name',
|
|
15
|
+
describe('name', () => {
|
|
16
|
+
test('Set name', () => {
|
|
17
17
|
const p = new Passage();
|
|
18
18
|
p.name = 'New';
|
|
19
19
|
expect(p.name).toBe('New');
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
test('Throw error if name is not String',
|
|
22
|
+
test('Throw error if name is not String', () => {
|
|
23
23
|
const p = new Passage();
|
|
24
24
|
expect(() => {
|
|
25
25
|
p.name = 1;
|
|
@@ -27,14 +27,14 @@ describe('Passage', function () {
|
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
describe('tags',
|
|
31
|
-
test('Set tags',
|
|
30
|
+
describe('tags', () => {
|
|
31
|
+
test('Set tags', () => {
|
|
32
32
|
const p = new Passage();
|
|
33
33
|
p.tags = ['tag'];
|
|
34
34
|
expect(p.tags).toHaveLength(1);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
test('Throw error if tags is not Array',
|
|
37
|
+
test('Throw error if tags is not Array', () => {
|
|
38
38
|
const p = new Passage();
|
|
39
39
|
expect(() => {
|
|
40
40
|
p.tags = 1;
|
|
@@ -42,14 +42,14 @@ describe('Passage', function () {
|
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
describe('metadata',
|
|
46
|
-
test('Set metadata',
|
|
45
|
+
describe('metadata', () => {
|
|
46
|
+
test('Set metadata', () => {
|
|
47
47
|
const p = new Passage();
|
|
48
48
|
p.metadata = { position: '100,100' };
|
|
49
49
|
expect(p.metadata).toEqual({ position: '100,100' });
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
test('Throw error if metadata is not an Object',
|
|
52
|
+
test('Throw error if metadata is not an Object', () => {
|
|
53
53
|
const p = new Passage();
|
|
54
54
|
expect(() => {
|
|
55
55
|
p.metadata = 1;
|
|
@@ -57,14 +57,14 @@ describe('Passage', function () {
|
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
describe('text',
|
|
61
|
-
test('Set text',
|
|
60
|
+
describe('text', () => {
|
|
61
|
+
test('Set text', () => {
|
|
62
62
|
const p = new Passage();
|
|
63
63
|
p.text = 'New';
|
|
64
64
|
expect(p.text).toBe('New');
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
test('Throw error if text is not a String',
|
|
67
|
+
test('Throw error if text is not a String', () => {
|
|
68
68
|
const p = new Passage();
|
|
69
69
|
expect(() => {
|
|
70
70
|
p.text = 1;
|
|
@@ -72,14 +72,14 @@ describe('Passage', function () {
|
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
-
describe('pid',
|
|
76
|
-
test('Set PID',
|
|
75
|
+
describe('pid', () => {
|
|
76
|
+
test('Set PID', () => {
|
|
77
77
|
const p = new Passage();
|
|
78
78
|
p.pid = 12;
|
|
79
79
|
expect(p.pid).toBe(12);
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
test('Throw error if pid is not a Number',
|
|
82
|
+
test('Throw error if pid is not a Number', () => {
|
|
83
83
|
const p = new Passage();
|
|
84
84
|
expect(() => {
|
|
85
85
|
p.pid = [];
|
|
@@ -87,16 +87,16 @@ describe('Passage', function () {
|
|
|
87
87
|
});
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
describe('toString()',
|
|
91
|
-
test('Create name string',
|
|
90
|
+
describe('toString()', () => {
|
|
91
|
+
test('Create name string', () => {
|
|
92
92
|
const p = new Passage('Name', 'Test');
|
|
93
93
|
expect(p.toString()).toBe(':: Name\nTest\n\n');
|
|
94
94
|
});
|
|
95
|
-
test('Create tags string',
|
|
95
|
+
test('Create tags string', () => {
|
|
96
96
|
const p = new Passage('Name', 'Test', ['tags', 'another']);
|
|
97
97
|
expect(p.toString()).toBe(':: Name [tags another]\nTest\n\n');
|
|
98
98
|
});
|
|
99
|
-
test('Create metadata string',
|
|
99
|
+
test('Create metadata string', () => {
|
|
100
100
|
const p = new Passage('Name', 'Test', ['tags', 'another'], { position: '100,100' });
|
|
101
101
|
expect(p.toString()).toBe(':: Name [tags another] {"position":"100,100"}\nTest\n\n');
|
|
102
102
|
});
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
<tw-story></tw-story>
|
|
13
13
|
|
|
14
|
-
<tw-storydata name="Example1" startnode="4" creator="extwee" creator-version="2.0.
|
|
14
|
+
<tw-storydata name="Example1" startnode="4" creator="extwee" creator-version="2.0.2" ifid="DBA67A9D-F81D-4F6D-8099-696CA6580AEC" zoom="0" format="Harlowe" format-version="3.0.2" options hidden>
|
|
15
15
|
<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>
|
|
16
16
|
<script role="script" id="twine-user-script" type="text/twine-javascript"></script>
|
|
17
17
|
<tw-passagedata pid="1" name="StoryTitle">Example1</tw-passagedata>
|
package/test/TweeParser.test.js
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
import FileReader from '../src/FileReader.js';
|
|
2
2
|
import TweeParser from '../src/TweeParser.js';
|
|
3
3
|
|
|
4
|
-
describe('TweeParser',
|
|
5
|
-
describe('#parse()',
|
|
6
|
-
|
|
4
|
+
describe('TweeParser', () => {
|
|
5
|
+
describe('#parse()', () => {
|
|
6
|
+
it('Should throw error if non-string is used', () => {
|
|
7
7
|
expect(() => { TweeParser.parse(1); }).toThrow();
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
it('Should throw error if empty string is used', () => {
|
|
11
11
|
expect(() => { TweeParser.parse(); }).toThrow();
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
it('Should throw error if no passages are present', () => {
|
|
15
15
|
expect(() => { TweeParser.parse('()()'); }).toThrow();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
it('Should throw error if it detects malformed passage headers', () => {
|
|
19
19
|
expect(() => { TweeParser.parse('::{}[]\nNo name'); }).toThrow();
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
it('Should cut notes before passages', () => {
|
|
23
23
|
const fr = FileReader.read('test/TweeParser/notes.twee');
|
|
24
24
|
const story = TweeParser.parse(fr);
|
|
25
25
|
const p = story.getPassageByName('StoryTitle');
|
|
26
26
|
expect(p.text).toBe('twineExample');
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
it('Should be able to parse Twee file for Story Name', () => {
|
|
30
30
|
const fr = FileReader.read('test/TweeParser/example.twee');
|
|
31
31
|
const story = TweeParser.parse(fr);
|
|
32
32
|
const p = story.getPassageByName('StoryTitle');
|
|
33
33
|
expect(p.text).toBe('twineExample');
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
it('Should parse single tag on Start passage', () => {
|
|
37
37
|
const fr = FileReader.read('test/TweeParser/singletag.twee');
|
|
38
38
|
const story = TweeParser.parse(fr);
|
|
39
39
|
const start = story.getPassageByName('Start');
|
|
40
40
|
expect(start.tags).toHaveLength(1);
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
it('Should parse multiple tag', () => {
|
|
44
44
|
const fr = FileReader.read('test/TweeParser/multipletags.twee');
|
|
45
45
|
const story = TweeParser.parse(fr);
|
|
46
46
|
const start = story.getPassageByName('Start');
|
|
47
47
|
expect(start.tags).toHaveLength(2);
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
it('Should parse single script passage', () => {
|
|
51
51
|
const fr = FileReader.read('test/TweeParser/scriptPassage.twee');
|
|
52
52
|
const story = TweeParser.parse(fr);
|
|
53
53
|
const p = story.getPassageByName('UserScript');
|
|
54
54
|
expect(p.tags).toHaveLength(1);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
it('Should parse single stylesheet passage', () => {
|
|
58
58
|
const fr = FileReader.read('test/TweeParser/stylePassage.twee');
|
|
59
59
|
const story = TweeParser.parse(fr);
|
|
60
60
|
const p = story.getPassageByName('UserStylesheet');
|
|
@@ -62,14 +62,14 @@ describe('TweeParser', function () {
|
|
|
62
62
|
expect(p.name).toBe('UserStylesheet');
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
it('Should parse StoryTitle', () => {
|
|
66
66
|
const fr = FileReader.read('test/TweeParser/test.twee');
|
|
67
67
|
const story = TweeParser.parse(fr);
|
|
68
68
|
const p = story.getPassageByName('StoryTitle');
|
|
69
69
|
expect(p).not.toBe(null);
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
it('Should parse StoryAuthor', () => {
|
|
73
73
|
const fr = FileReader.read('test/TweeParser/example.twee');
|
|
74
74
|
const story = TweeParser.parse(fr);
|
|
75
75
|
const p = story.getPassageByName('StoryAuthor');
|
package/test/TweeWriter.test.js
CHANGED
|
@@ -4,18 +4,23 @@ import Passage from '../src/Passage.js';
|
|
|
4
4
|
import TweeWriter from '../src/TweeWriter.js';
|
|
5
5
|
import TweeParser from '../src/TweeParser.js';
|
|
6
6
|
|
|
7
|
-
describe('TweeWriter',
|
|
8
|
-
describe('#write()',
|
|
9
|
-
|
|
7
|
+
describe('TweeWriter', () => {
|
|
8
|
+
describe('#write()', () => {
|
|
9
|
+
let s = null;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
s = new Story();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('Should throw error if object passed is not instanceof Story', () => {
|
|
10
16
|
expect(() => { TweeWriter.write({}); }).toThrow();
|
|
11
17
|
});
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
it('Should throw error if output file invalid', () => {
|
|
14
20
|
expect(() => { TweeWriter.write(new Story(), ''); }).toThrow();
|
|
15
21
|
});
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
const s = new Story();
|
|
23
|
+
it('Should write Twee file', () => {
|
|
19
24
|
s.addPassage(new Passage('StoryData', '{}'));
|
|
20
25
|
s.addPassage(new Passage('StoryTitle', 'Title'));
|
|
21
26
|
s.addPassage(new Passage('Start', 'Content'));
|
|
@@ -26,8 +31,7 @@ describe('TweeWriter', function () {
|
|
|
26
31
|
expect(p.text).toBe('Title');
|
|
27
32
|
});
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
const s = new Story();
|
|
34
|
+
it('Should correctly write Twee file with passage tags', () => {
|
|
31
35
|
s.addPassage(new Passage('Start', '', ['tag', 'tags']));
|
|
32
36
|
s.addPassage(new Passage('StoryTitle', 'Title'));
|
|
33
37
|
// Verify only one passage.
|
|
@@ -46,8 +50,7 @@ describe('TweeWriter', function () {
|
|
|
46
50
|
expect(tp.size()).toBe(2);
|
|
47
51
|
});
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
const s = new Story();
|
|
53
|
+
it('Should write format, formatVersion, zoom, and start', () => {
|
|
51
54
|
s.addPassage(new Passage('StoryTitle', 'Title'));
|
|
52
55
|
s.addPassage(new Passage('Start', 'Content'));
|
|
53
56
|
s.addPassage(new Passage('Untitled', 'Some stuff'));
|
|
@@ -60,11 +63,11 @@ describe('TweeWriter', function () {
|
|
|
60
63
|
TweeWriter.write(s, 'test/TweeWriter/test1.twee');
|
|
61
64
|
const fr = FileReader.read('test/TweeWriter/test1.twee');
|
|
62
65
|
const story2 = TweeParser.parse(fr);
|
|
66
|
+
console.log(story2);
|
|
63
67
|
expect(story2.format).toBe('Test');
|
|
64
68
|
});
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
const s = new Story();
|
|
70
|
+
it('Should write tag colors', () => {
|
|
68
71
|
s.addPassage(new Passage('StoryTitle', 'Title'));
|
|
69
72
|
s.addPassage(new Passage('Start', 'Content'));
|
|
70
73
|
s.addPassage(new Passage('Untitled', 'Some stuff'));
|