Skip to content

Commit e1e5f41

Browse files
ashfordneilmetricjslnewsonJamesToohey
authored
TINY-7564: Add part 3 (dealing with TinyMCE part II) (#12)
Co-authored-by: metricjs <[email protected]> Co-authored-by: Lee Newson <[email protected]> Co-authored-by: JamesToohey <[email protected]>
1 parent 630a4f5 commit e1e5f41

13 files changed

+461
-137
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ Anything with a TODO is something you need to fill in.
2020

2121
When you're finished a section, let your tutor know and they will review your code.
2222

23+
The tutorial is in 3 parts. They are located:
24+
25+
| Part | Location |
26+
| ---- | -------- |
27+
| 1 | `src/main/html` |
28+
| 2 | `src/main/ts` and `src/test/ts/part2` |
29+
| 3 | `src/test/ts/part3` |
30+
2331
# Tips
2432

2533
Follow the types.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222
"@ephox/sugar": "^7.0.1"
2323
},
2424
"devDependencies": {
25+
"@ephox/agar": "^5.3.1",
2526
"@ephox/bedrock-client": "^11.1.1",
2627
"@ephox/bedrock-server": "^11.2.0",
28+
"@ephox/mcagar": "^6.1.1",
29+
"@types/chai": "^4.2.18",
2730
"awesome-typescript-loader": "^5.2.1",
31+
"chai": "^4.3.4",
2832
"fast-check": "^2.2.1",
33+
"tinymce": "^5.8.1",
2934
"typescript": "^4.0.2",
3035
"webpack": "^4.44.1",
3136
"webpack-cli": "^3.3.12",

src/main/ts/Part2Ex3Optional.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { Optional } from '@ephox/katamari';
44
Optional
55
66
NOTE: In TinyMCE 5.4 and earlier, this type is known as Option.
7-
This codebase currently uses an old version, but we're renaming the import to match the new name.
87
98
Programming is all about writing functions to compute values. But quite often we have functions that can't return a
109
value in all cases. Some examples:
@@ -92,7 +91,7 @@ The last function you implemented is already part of the Optional type, and is c
9291
There's a corresponding isNone().
9392
9493
In some VERY LIMITED SITUATIONS you can use isSome() and then the UNSAFE getOrDie() function.
95-
It's acceptible to do this in tests, or where nested folding is incredibly cumbersome.
94+
It's acceptable to do this in tests, or where nested folding is incredibly cumbersome.
9695
*/
9796

9897
export const unsafeStuff = (e: Optional<string>): void => {
@@ -102,16 +101,6 @@ export const unsafeStuff = (e: Optional<string>): void => {
102101
};
103102

104103
/*
105-
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
106-
+
107-
+ Aside: But you said we used "static" functions, not methods on objects!
108-
+
109-
+ Yeah, mostly we do. But Optional is from a time before we pushed that concept very hard.
110-
+ At some point, we intend to replace Optional's API with something fully static.
111-
+
112-
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
113-
114-
115104
A common way to handle an Optional value is to provide a default value if in the case of none.
116105
117106
You can do this with fold, but getOr is a shortcut.

src/main/ts/Part2Ex5Sugar.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,16 @@ Sugar smooths over browser differences and gives us useful functions for manipul
99
When using Sugar, we don't use native DOM elements, we wrap them in the SugarElement data type.
1010
This encourages us to only use Sugar functions to manipulate these elements, rather than the native DOM directly.
1111
12-
NOTE: Like Option=>Optional, Sugar is in the process of renaming. This tutorial is using the old libraries, but we'll
13-
rename imports to use the new names.
14-
1512
Wrapping
1613
1714
The first thing we need to know is how to wrap and unwrap a sugar element.
1815
*/
1916

2017

21-
const e1: Element = document.createElement('span');
18+
const e1: HTMLSpanElement = document.createElement('span');
2219

2320
// wrapping
24-
const se1: SugarElement<Element> = SugarElement.fromDom(e1);
21+
const se1: SugarElement<HTMLSpanElement> = SugarElement.fromDom(e1);
2522

2623
// unwrapping
2724
const e2: Element = se1.dom;
@@ -32,11 +29,11 @@ Pretty simple so far.
3229
Now, above, we used `document.createElement`. We want to use Sugar functions everywhere, so we should do this instead:
3330
*/
3431

35-
const se2: SugarElement<Element> = SugarElement.fromTag('span');
32+
const se2: SugarElement<HTMLSpanElement> = SugarElement.fromTag('span');
3633

3734
// or
3835

39-
const se3: SugarElement<Element> = SugarElement.fromTag('span', document);
36+
const se3: SugarElement<HTMLSpanElement> = SugarElement.fromTag('span', document);
4037

4138
/*
4239
It's useful to be able to pass in a document parameter to this function, since we're often dealing with iframes as well
@@ -50,8 +47,8 @@ TODO: Use SugarElement's fromHtml and fromText functions to create a few element
5047
We often have to traverse from an element to its relatives. The Traverse module has useful functions for this.
5148
*/
5249
() => {
53-
const parent: SugarElement<Element> = SugarElement.fromTag('div');
54-
const kid: SugarElement<Element> = SugarElement.fromTag('span');
50+
const parent: SugarElement<HTMLDivElement> = SugarElement.fromTag('div');
51+
const kid: SugarElement<HTMLSpanElement> = SugarElement.fromTag('span');
5552
Insert.append(parent, kid);
5653

5754
const parent2 = Traverse.parent(kid);
@@ -63,9 +60,9 @@ We often have to traverse from an element to its relatives. The Traverse module
6360

6461

6562
() => {
66-
const parent: SugarElement<Element> = SugarElement.fromTag('div');
67-
const kid1: SugarElement<Element> = SugarElement.fromTag('span');
68-
const kid2: SugarElement<Element> = SugarElement.fromTag('div');
63+
const parent: SugarElement<HTMLDivElement> = SugarElement.fromTag('div');
64+
const kid1: SugarElement<HTMLSpanElement> = SugarElement.fromTag('span');
65+
const kid2: SugarElement<HTMLDivElement> = SugarElement.fromTag('div');
6966
Insert.append(parent, kid1);
7067
Insert.append(parent, kid2);
7168

src/test/ts/Exercise1CodeStyleTest.ts

Lines changed: 0 additions & 57 deletions
This file was deleted.

src/test/ts/Exercise2ArrayFunctionsTest.ts

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/test/ts/Exercise3OptionTest.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { describe, it } from '@ephox/bedrock-client';
2+
import { assert } from 'chai';
3+
import * as CodeStyle from '../../../main/ts/Part2Ex1';
4+
5+
type Boundz = CodeStyle.Boundz;
6+
7+
/*
8+
We run tests using an internally developed test runner called Bedrock.
9+
Bedrock lets us easily run js tests across different browsers.
10+
11+
1. Running tests with bedrock
12+
13+
Bedrock can be run manually or automatically. Manual will start a test server on a local port, you can then
14+
access this with any browser to run the tests. Auto will require you specify a target browser.
15+
16+
To test this file with bedrock, run this command and then open the page in any browser:
17+
yarn bedrock -f src/test/ts/part2/Exercise1CodeStyleTest.ts
18+
19+
Alternatively you can run bedrock-auto and provide a browser as an argument
20+
21+
To test this file with bedrock-auto in a headless browser, run:
22+
yarn bedrock-auto -b chrome-headless -f src/test/ts/part2/Exercise1CodeStyleTest.ts
23+
24+
If you want to run this in a full browser, try:
25+
yarn bedrock-auto -b chrome -f src/test/ts/part2/Exercise1CodeStyleTest.ts
26+
27+
TODO: Run bedrock in all modes shown above.
28+
29+
2. Defining tests
30+
31+
Bedrock aims to match the mocha BDD API style which uses describe, context and it.
32+
33+
https://mochajs.org/#getting-started
34+
35+
We start with a definition like this...
36+
*/
37+
describe('Exercise1CodeStyleTests', () => {
38+
it('width', () => {
39+
// ... and then we write some test cases
40+
// We use chai assertions https://www.chaijs.com/api/assert/
41+
42+
const b: Boundz = ({ x1: 3, y1: 4, x2: 7, y2: 8 });
43+
assert.deepEqual(CodeStyle.width(b), 4, 'Width');
44+
45+
// TODO: write another test case for width
46+
});
47+
48+
/*
49+
3. Testing 'height' function
50+
51+
We can have multiple "it" calls in one "describe". This is how we separate tests.
52+
In this case, we'll call "it" again, to write a test for 'height'
53+
54+
*/
55+
// TODO: write a simple test case for height
56+
57+
/*
58+
4. Test output
59+
60+
The below test should fail.
61+
62+
TODO: remove the ".skip" to enable this test. Run it using the commands above.
63+
Notice that the output shows a diff.
64+
TODO: Correct the test and run it again.
65+
66+
*/
67+
68+
it.skip('failing test', () => {
69+
assert.deepEqual({ a: 1, b: 2 }, { a: 1, b: 7, c: 8 });
70+
});
71+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { describe, it } from '@ephox/bedrock-client';
2+
import { assert } from 'chai';
3+
import * as Ex from '../../../main/ts/Part2Ex2ArrayFunctions';
4+
5+
describe('Exercise2ArrayFunctionsTest', () => {
6+
it('runEach1', () => {
7+
Ex.runEach1();
8+
});
9+
10+
it('frog names', () => {
11+
assert.deepEqual(Ex.frogNames(Ex.myFrogs), [ 'frog1', 'frog2', 'loudfrog', 'quietfrog' ], 'frog names');
12+
});
13+
14+
it('frog ages', () => {
15+
// TODO: write a test for your frog ages function
16+
});
17+
18+
it('ribbitting frogs', () => {
19+
assert.deepEqual(Ex.ribbitting(Ex.myFrogs), [
20+
{ name: 'frog1', ribbits: true, age: 3 },
21+
{ name: 'loudfrog', ribbits: true, age: 1 }
22+
], 'ribbitting');
23+
});
24+
25+
it('older frogs', () => {
26+
assert.deepEqual(Ex.olderFrogs(Ex.myFrogs), [
27+
{ name: 'quietfrog', ribbits: false, age: 10 }
28+
], 'older frogs');
29+
});
30+
31+
it('csvs', () => {
32+
assert.deepEqual(Ex.splitCsvs([]), [], 'empty array');
33+
assert.deepEqual(Ex.splitCsvs(['a']), ['a'], 'single string');
34+
assert.deepEqual(Ex.splitCsvs(['a,b']), ['a', 'b'], 'single csv string');
35+
assert.deepEqual(Ex.splitCsvs(['a', 'b']), ['a', 'b'], 'several strings');
36+
assert.deepEqual(Ex.splitCsvs(['a', 'b,d,a']), ['a', 'b', 'd', 'a'], 'several csv strings');
37+
});
38+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, it } from '@ephox/bedrock-client';
2+
import { assert } from 'chai';
3+
import * as Ex from '../../../main/ts/Part2Ex3Optional';
4+
5+
describe('Exercise3OptionTest', () => {
6+
it('getProtocol', () => {
7+
assert.equal(Ex.getProtocol('https://frog.com').getOrDie(), 'https');
8+
assert.equal(Ex.getProtocol('http://frog.com').getOrDie(), 'http');
9+
assert.isTrue(Ex.getProtocol('frog.com').isNone(), 'no protocol should be found');
10+
assert.isTrue(Ex.getProtocol('://frog.com').isNone(), 'no protocol should be found');
11+
assert.isTrue(Ex.getProtocol('3ttp://frog.com').isNone(), 'malformed protocol should not be registered');
12+
});
13+
14+
it('toPositiveInteger', () => {
15+
// TODO: write a few test cases
16+
});
17+
});
18+
19+
// TODO: Now that you have finished all the test files in this directory,
20+
// try running all tests in the "part2" folder all using the `-d` argument in bedrock and specifying the parent directory.

0 commit comments

Comments
 (0)