trackler 2.2.1.71 → 2.2.1.72
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/book-store/canonical-data.json +9 -2
- data/problem-specifications/exercises/word-count/canonical-data.json +9 -0
- data/tracks/bash/CONTRIBUTING.md +199 -0
- data/tracks/bash/config.json +24 -11
- data/tracks/bash/exercises/triangle/README.md +38 -0
- data/tracks/bash/exercises/triangle/example.sh +56 -0
- data/tracks/bash/exercises/triangle/triangle_test.sh +126 -0
- data/tracks/bash/img/canonical-data-example.png +0 -0
- data/tracks/bash/img/create-pr.png +0 -0
- data/tracks/bash/img/fork-repository.png +0 -0
- data/tracks/c/exercises/acronym/makefile +1 -1
- data/tracks/c/exercises/all-your-base/makefile +1 -1
- data/tracks/c/exercises/allergies/makefile +1 -1
- data/tracks/c/exercises/anagram/makefile +1 -1
- data/tracks/c/exercises/atbash-cipher/makefile +1 -1
- data/tracks/c/exercises/beer-song/makefile +1 -1
- data/tracks/c/exercises/binary-search/makefile +1 -1
- data/tracks/c/exercises/binary/makefile +1 -1
- data/tracks/c/exercises/bob/makefile +1 -1
- data/tracks/c/exercises/clock/makefile +1 -1
- data/tracks/c/exercises/collatz-conjecture/makefile +1 -1
- data/tracks/c/exercises/difference-of-squares/makefile +1 -1
- data/tracks/c/exercises/gigasecond/makefile +1 -1
- data/tracks/c/exercises/grains/makefile +1 -1
- data/tracks/c/exercises/hamming/makefile +1 -1
- data/tracks/c/exercises/hamming/test/test_hamming.c +2 -2
- data/tracks/c/exercises/hello-world/makefile +1 -1
- data/tracks/c/exercises/isogram/makefile +1 -1
- data/tracks/c/exercises/largest-series-product/makefile +1 -1
- data/tracks/c/exercises/leap/makefile +1 -1
- data/tracks/c/exercises/meetup/makefile +1 -1
- data/tracks/c/exercises/nth-prime/makefile +1 -1
- data/tracks/c/exercises/nucleotide-count/makefile +1 -1
- data/tracks/c/exercises/palindrome-products/makefile +1 -1
- data/tracks/c/exercises/pangram/makefile +1 -1
- data/tracks/c/exercises/pascals-triangle/makefile +1 -1
- data/tracks/c/exercises/perfect-numbers/makefile +1 -1
- data/tracks/c/exercises/phone-number/makefile +1 -1
- data/tracks/c/exercises/queen-attack/makefile +1 -1
- data/tracks/c/exercises/raindrops/makefile +1 -1
- data/tracks/c/exercises/react/makefile +1 -1
- data/tracks/c/exercises/rna-transcription/makefile +1 -1
- data/tracks/c/exercises/robot-simulator/makefile +1 -1
- data/tracks/c/exercises/roman-numerals/makefile +1 -1
- data/tracks/c/exercises/scrabble-score/makefile +1 -1
- data/tracks/c/exercises/series/makefile +1 -1
- data/tracks/c/exercises/sieve/makefile +1 -1
- data/tracks/c/exercises/space-age/makefile +1 -1
- data/tracks/c/exercises/sublist/makefile +1 -1
- data/tracks/c/exercises/sum-of-multiples/makefile +1 -1
- data/tracks/c/exercises/triangle/makefile +1 -1
- data/tracks/c/exercises/word-count/makefile +1 -1
- data/tracks/delphi/exercises/allergies/README.md +1 -1
- data/tracks/delphi/exercises/bank-account/README.md +1 -1
- data/tracks/delphi/exercises/beer-song/README.md +1 -1
- data/tracks/delphi/exercises/binary-search/README.md +1 -1
- data/tracks/delphi/exercises/bob/README.md +1 -1
- data/tracks/delphi/exercises/book-store/README.md +1 -1
- data/tracks/delphi/exercises/book-store/uBookStoreExample.pas +34 -14
- data/tracks/delphi/exercises/book-store/uBookStoreTests.pas +36 -1
- data/tracks/delphi/exercises/bowling/README.md +1 -1
- data/tracks/delphi/exercises/circular-buffer/README.md +1 -1
- data/tracks/delphi/exercises/clock/README.md +1 -1
- data/tracks/delphi/exercises/collatz-conjecture/README.md +1 -1
- data/tracks/delphi/exercises/etl/README.md +1 -1
- data/tracks/delphi/exercises/grains/README.md +1 -1
- data/tracks/delphi/exercises/hamming/README.md +1 -1
- data/tracks/delphi/exercises/hello-world/README.md +1 -1
- data/tracks/delphi/exercises/leap/README.md +1 -1
- data/tracks/delphi/exercises/minesweeper/README.md +1 -1
- data/tracks/delphi/exercises/nucleotide-count/README.md +1 -1
- data/tracks/delphi/exercises/perfect-numbers/README.md +1 -1
- data/tracks/delphi/exercises/phone-number/README.md +1 -1
- data/tracks/delphi/exercises/pig-latin/README.md +1 -1
- data/tracks/delphi/exercises/poker/README.md +1 -1
- data/tracks/delphi/exercises/raindrops/README.md +1 -1
- data/tracks/delphi/exercises/reverse-string/README.md +1 -1
- data/tracks/delphi/exercises/rna-transcription/README.md +1 -1
- data/tracks/delphi/exercises/roman-numerals/README.md +1 -1
- data/tracks/delphi/exercises/saddle-points/README.md +1 -1
- data/tracks/delphi/exercises/triangle/README.md +1 -1
- data/tracks/delphi/exercises/two-fer/README.md +1 -1
- data/tracks/delphi/exercises/wordy/README.md +1 -1
- data/tracks/ecmascript/.travis.yml +1 -1
- data/tracks/ecmascript/Makefile +4 -5
- data/tracks/ecmascript/README.md +2 -1
- data/tracks/ecmascript/config.json +12 -0
- data/tracks/ecmascript/exercises/change/package.json +5 -3
- data/tracks/ecmascript/exercises/protein-translation/package.json +2 -2
- data/tracks/ecmascript/exercises/react/README.md +41 -0
- data/tracks/ecmascript/exercises/react/example.js +101 -0
- data/tracks/ecmascript/exercises/react/package.json +71 -0
- data/tracks/ecmascript/exercises/react/react.spec.js +211 -0
- data/tracks/ecmascript/exercises/rectangles/package.json +1 -2
- data/tracks/ecmascript/exercises/rotational-cipher/package.json +1 -2
- data/tracks/ecmascript/exercises/spiral-matrix/package.json +1 -2
- data/tracks/ecmascript/exercises/transpose/package.json +2 -2
- data/tracks/erlang/docs/ABOUT.md +1 -1
- data/tracks/go/exercises/binary-search/.meta/gen.go +55 -0
- data/tracks/go/exercises/binary-search/binary_search_test.go +26 -167
- data/tracks/go/exercises/binary-search/cases_test.go +73 -0
- data/tracks/go/exercises/binary-search/example.go +8 -30
- data/tracks/go/exercises/nth-prime/.meta/gen.go +76 -0
- data/tracks/go/exercises/nth-prime/cases_test.go +43 -0
- data/tracks/go/exercises/nth-prime/nth_prime_test.go +4 -18
- data/tracks/go/exercises/prime-factors/.meta/gen.go +54 -0
- data/tracks/go/exercises/prime-factors/cases_test.go +48 -0
- data/tracks/go/exercises/prime-factors/prime_factors_test.go +4 -19
- data/tracks/groovy/config.json +13 -1
- data/tracks/groovy/exercises/linked-list/DoubleLinkedList.groovy +19 -0
- data/tracks/groovy/exercises/linked-list/DoubleLinkedListSpec.groovy +79 -0
- data/tracks/groovy/exercises/linked-list/Example.groovy +57 -0
- data/tracks/groovy/exercises/linked-list/README.md +49 -0
- data/tracks/java/bin/run-journey-test-from-ci.sh +1 -1
- data/tracks/java/config.json +10 -0
- data/tracks/java/config/maintainers.json +8 -1
- data/tracks/java/docs/MAINTAINING.md +3 -3
- data/tracks/java/exercises/accumulate/.meta/src/reference/java/Accumulate.java +2 -2
- data/tracks/java/exercises/binary/.meta/src/reference/java/Binary.java +3 -3
- data/tracks/java/exercises/circular-buffer/.meta/src/reference/java/BufferIOException.java +1 -1
- data/tracks/java/exercises/circular-buffer/.meta/src/reference/java/CircularBuffer.java +6 -6
- data/tracks/java/exercises/circular-buffer/src/main/java/BufferIOException.java +1 -1
- data/tracks/java/exercises/clock/.meta/src/reference/java/Clock.java +3 -3
- data/tracks/java/exercises/crypto-square/.meta/src/reference/java/Crypto.java +7 -7
- data/tracks/java/exercises/etl/.meta/src/reference/java/Etl.java +2 -2
- data/tracks/java/exercises/etl/src/main/java/Etl.java +2 -2
- data/tracks/java/exercises/kindergarten-garden/.meta/src/reference/java/KindergartenGarden.java +4 -4
- data/tracks/java/exercises/kindergarten-garden/.meta/src/reference/java/Plant.java +2 -2
- data/tracks/java/exercises/kindergarten-garden/src/main/java/Plant.java +2 -2
- data/tracks/java/exercises/nth-prime/.meta/src/reference/java/PrimeCalculator.java +2 -2
- data/tracks/java/exercises/reverse-string/.meta/src/reference/java/ReverseString.java +7 -0
- data/tracks/java/exercises/reverse-string/.meta/version +1 -0
- data/tracks/java/exercises/reverse-string/README.md +25 -0
- data/tracks/java/exercises/reverse-string/build.gradle +17 -0
- data/tracks/java/exercises/reverse-string/src/main/java/ReverseString.java +7 -0
- data/tracks/java/exercises/reverse-string/src/test/java/ReverseStringTest.java +37 -0
- data/tracks/java/exercises/run-length-encoding/.meta/src/reference/java/RunLengthEncoding.java +4 -4
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/kotlin/docs/RESOURCES.md +1 -1
- data/tracks/kotlin/exercises/accumulate/build.gradle +1 -1
- data/tracks/kotlin/exercises/acronym/build.gradle +1 -1
- data/tracks/kotlin/exercises/all-your-base/build.gradle +1 -1
- data/tracks/kotlin/exercises/allergies/build.gradle +1 -1
- data/tracks/kotlin/exercises/anagram/build.gradle +1 -1
- data/tracks/kotlin/exercises/atbash-cipher/build.gradle +1 -1
- data/tracks/kotlin/exercises/bank-account/build.gradle +1 -1
- data/tracks/kotlin/exercises/beer-song/build.gradle +1 -1
- data/tracks/kotlin/exercises/binary-search/build.gradle +1 -1
- data/tracks/kotlin/exercises/binary/build.gradle +1 -1
- data/tracks/kotlin/exercises/bob/build.gradle +1 -1
- data/tracks/kotlin/exercises/bracket-push/build.gradle +1 -1
- data/tracks/kotlin/exercises/change/build.gradle +1 -1
- data/tracks/kotlin/exercises/clock/build.gradle +1 -1
- data/tracks/kotlin/exercises/collatz-conjecture/build.gradle +1 -1
- data/tracks/kotlin/exercises/complex-numbers/build.gradle +1 -1
- data/tracks/kotlin/exercises/diamond/build.gradle +1 -1
- data/tracks/kotlin/exercises/difference-of-squares/build.gradle +1 -1
- data/tracks/kotlin/exercises/etl/build.gradle +1 -1
- data/tracks/kotlin/exercises/flatten-array/build.gradle +1 -1
- data/tracks/kotlin/exercises/forth/build.gradle +1 -1
- data/tracks/kotlin/exercises/gigasecond/build.gradle +1 -1
- data/tracks/kotlin/exercises/grade-school/build.gradle +1 -1
- data/tracks/kotlin/exercises/grains/build.gradle +1 -1
- data/tracks/kotlin/exercises/hamming/build.gradle +1 -1
- data/tracks/kotlin/exercises/hello-world/build.gradle +1 -1
- data/tracks/kotlin/exercises/hexadecimal/build.gradle +1 -1
- data/tracks/kotlin/exercises/isogram/build.gradle +1 -1
- data/tracks/kotlin/exercises/largest-series-product/build.gradle +1 -1
- data/tracks/kotlin/exercises/leap/build.gradle +1 -1
- data/tracks/kotlin/exercises/linked-list/build.gradle +1 -1
- data/tracks/kotlin/exercises/list-ops/build.gradle +1 -1
- data/tracks/kotlin/exercises/luhn/build.gradle +1 -1
- data/tracks/kotlin/exercises/meetup/build.gradle +1 -1
- data/tracks/kotlin/exercises/minesweeper/build.gradle +1 -1
- data/tracks/kotlin/exercises/nth-prime/build.gradle +1 -1
- data/tracks/kotlin/exercises/nucleotide-count/build.gradle +1 -1
- data/tracks/kotlin/exercises/pangram/build.gradle +1 -1
- data/tracks/kotlin/exercises/pascals-triangle/build.gradle +1 -1
- data/tracks/kotlin/exercises/perfect-numbers/build.gradle +1 -1
- data/tracks/kotlin/exercises/phone-number/build.gradle +1 -1
- data/tracks/kotlin/exercises/pig-latin/build.gradle +1 -1
- data/tracks/kotlin/exercises/prime-factors/build.gradle +1 -1
- data/tracks/kotlin/exercises/raindrops/build.gradle +1 -1
- data/tracks/kotlin/exercises/react/build.gradle +1 -1
- data/tracks/kotlin/exercises/rna-transcription/build.gradle +1 -1
- data/tracks/kotlin/exercises/robot-name/build.gradle +1 -1
- data/tracks/kotlin/exercises/robot-simulator/build.gradle +1 -1
- data/tracks/kotlin/exercises/roman-numerals/build.gradle +1 -1
- data/tracks/kotlin/exercises/rotational-cipher/build.gradle +1 -1
- data/tracks/kotlin/exercises/saddle-points/build.gradle +1 -1
- data/tracks/kotlin/exercises/say/build.gradle +1 -1
- data/tracks/kotlin/exercises/scrabble-score/build.gradle +1 -1
- data/tracks/kotlin/exercises/secret-handshake/build.gradle +1 -1
- data/tracks/kotlin/exercises/series/build.gradle +1 -1
- data/tracks/kotlin/exercises/sieve/build.gradle +1 -1
- data/tracks/kotlin/exercises/simple-cipher/README.md +4 -6
- data/tracks/kotlin/exercises/simple-cipher/build.gradle +1 -1
- data/tracks/kotlin/exercises/space-age/build.gradle +1 -1
- data/tracks/kotlin/exercises/spiral-matrix/build.gradle +1 -1
- data/tracks/kotlin/exercises/strain/build.gradle +1 -1
- data/tracks/kotlin/exercises/sublist/build.gradle +1 -1
- data/tracks/kotlin/exercises/sum-of-multiples/build.gradle +1 -1
- data/tracks/kotlin/exercises/triangle/build.gradle +1 -1
- data/tracks/kotlin/exercises/two-fer/build.gradle +1 -1
- data/tracks/kotlin/exercises/word-count/build.gradle +1 -1
- data/tracks/lua/.gitignore +1 -0
- data/tracks/lua/config.json +12 -0
- data/tracks/lua/exercises/isbn-verifier/README.md +52 -0
- data/tracks/lua/exercises/isbn-verifier/example.lua +16 -0
- data/tracks/lua/exercises/isbn-verifier/isbn-verifier_spec.lua +55 -0
- data/tracks/ocaml/.travis-ci.sh +1 -1
- data/tracks/ocaml/.travis.yml +1 -1
- data/tracks/ocaml/README.md +1 -1
- data/tracks/perl6/config.json +10 -0
- data/tracks/perl6/exercises/acronym/Acronym.pm6 +4 -0
- data/tracks/perl6/exercises/acronym/Example.pm6 +5 -0
- data/tracks/perl6/exercises/acronym/README.md +33 -0
- data/tracks/perl6/exercises/acronym/acronym.t +96 -0
- data/tracks/perl6/exercises/acronym/example.yaml +19 -0
- data/tracks/perl6/exercises/word-count/Example.pm6 +1 -1
- data/tracks/perl6/exercises/word-count/WordCount.pm6 +1 -1
- data/tracks/perl6/exercises/word-count/example.yaml +2 -2
- data/tracks/perl6/exercises/word-count/word-count.t +11 -2
- data/tracks/pony/docs/RESOURCES.md +1 -1
- data/tracks/purescript/docs/INSTALLATION.md +1 -3
- data/tracks/python/config.json +1 -1
- data/tracks/r/exercises/word-count/test_word-count.R +5 -0
- data/tracks/ruby/README.md +73 -10
- data/tracks/rust/config.json +34 -0
- data/tracks/rust/exercises/book-store/Cargo.toml +1 -1
- data/tracks/rust/exercises/book-store/tests/book-store.rs +7 -0
- data/tracks/rust/exercises/diffie-hellman/.gitignore +9 -0
- data/tracks/rust/exercises/diffie-hellman/Cargo-example.toml +6 -0
- data/tracks/rust/exercises/diffie-hellman/Cargo.toml +5 -0
- data/tracks/rust/exercises/diffie-hellman/README.md +77 -0
- data/tracks/rust/exercises/diffie-hellman/example.rs +15 -0
- data/tracks/rust/exercises/diffie-hellman/src/lib.rs +11 -0
- data/tracks/rust/exercises/diffie-hellman/tests/diffie-hellman.rs +60 -0
- data/tracks/rust/exercises/macros/.gitignore +3 -0
- data/tracks/rust/exercises/macros/.meta/description.md +29 -0
- data/tracks/rust/exercises/macros/.meta/metadata.yml +3 -0
- data/tracks/rust/exercises/macros/Cargo.toml +6 -0
- data/tracks/rust/exercises/macros/README.md +70 -0
- data/tracks/rust/exercises/macros/example.rs +16 -0
- data/tracks/rust/exercises/macros/src/lib.rs +6 -0
- data/tracks/rust/exercises/macros/tests/macros.rs +62 -0
- data/tracks/rust/exercises/simple-linked-list/.gitignore +7 -0
- data/tracks/rust/exercises/simple-linked-list/.meta/hints.md +34 -0
- data/tracks/rust/exercises/simple-linked-list/Cargo.toml +5 -0
- data/tracks/rust/exercises/simple-linked-list/README.md +96 -0
- data/tracks/rust/exercises/simple-linked-list/example.rs +87 -0
- data/tracks/rust/exercises/simple-linked-list/src/lib.rs +46 -0
- data/tracks/rust/exercises/simple-linked-list/tests/simple-linked-list.rs +91 -0
- data/tracks/swift/.travis.yml +1 -1
- data/tracks/swift/config.json +24 -0
- data/tracks/swift/exercises/isbn-verifier/Package.swift +5 -0
- data/tracks/swift/exercises/isbn-verifier/README.md +39 -0
- data/tracks/swift/exercises/isbn-verifier/Sources/IsbnVerifier.swift +1 -0
- data/tracks/swift/exercises/isbn-verifier/Sources/IsbnVerifierExample.swift +35 -0
- data/tracks/swift/exercises/isbn-verifier/Tests/IsbnVerifierTests/IsbnVerifierTests.swift +75 -0
- data/tracks/swift/exercises/isbn-verifier/Tests/LinuxMain.swift +6 -0
- data/tracks/swift/exercises/two-fer/Package.swift +5 -0
- data/tracks/swift/exercises/two-fer/README.md +54 -0
- data/tracks/swift/exercises/two-fer/Sources/TwoFer.swift +1 -0
- data/tracks/swift/exercises/two-fer/Sources/TwoFerExample.swift +6 -0
- data/tracks/swift/exercises/two-fer/Tests/LinuxMain.swift +6 -0
- data/tracks/swift/exercises/two-fer/Tests/TwoFerTests/TwoFerTests.swift +25 -0
- metadata +71 -2
@@ -9,7 +9,7 @@
|
|
9
9
|
"url": "https://github.com/exercism/xecmascript"
|
10
10
|
},
|
11
11
|
"devDependencies": {
|
12
|
-
"babel-jest": "^
|
12
|
+
"babel-jest": "^21.2.0",
|
13
13
|
"babel-plugin-transform-builtin-extend": "^1.1.2",
|
14
14
|
"babel-preset-env": "^1.4.0",
|
15
15
|
"eslint": "^3.19.0",
|
@@ -17,7 +17,7 @@
|
|
17
17
|
"eslint-plugin-import": "^2.2.0",
|
18
18
|
"eslint-plugin-jsx-a11y": "^5.0.1",
|
19
19
|
"eslint-plugin-react": "^7.0.1",
|
20
|
-
"jest": "^
|
20
|
+
"jest": "^21.2.1"
|
21
21
|
},
|
22
22
|
"jest": {
|
23
23
|
"modulePathIgnorePatterns": [
|
@@ -37,7 +37,9 @@
|
|
37
37
|
]
|
38
38
|
}
|
39
39
|
],
|
40
|
-
[
|
40
|
+
[
|
41
|
+
"transform-regenerator"
|
42
|
+
]
|
41
43
|
]
|
42
44
|
},
|
43
45
|
"scripts": {
|
@@ -9,7 +9,7 @@
|
|
9
9
|
"url": "https://github.com/exercism/xecmascript"
|
10
10
|
},
|
11
11
|
"devDependencies": {
|
12
|
-
"babel-jest": "^
|
12
|
+
"babel-jest": "^21.2.0",
|
13
13
|
"babel-plugin-transform-builtin-extend": "^1.1.2",
|
14
14
|
"babel-preset-env": "^1.4.0",
|
15
15
|
"eslint": "^3.19.0",
|
@@ -17,7 +17,7 @@
|
|
17
17
|
"eslint-plugin-import": "^2.2.0",
|
18
18
|
"eslint-plugin-jsx-a11y": "^5.0.1",
|
19
19
|
"eslint-plugin-react": "^7.0.1",
|
20
|
-
"jest": "^
|
20
|
+
"jest": "^21.2.1"
|
21
21
|
},
|
22
22
|
"jest": {
|
23
23
|
"modulePathIgnorePatterns": [
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# React
|
2
|
+
|
3
|
+
Implement a basic reactive system.
|
4
|
+
|
5
|
+
Reactive programming is a programming paradigm that focuses on how values
|
6
|
+
are computed in terms of each other to allow a change to one value to
|
7
|
+
automatically propagate to other values, like in a spreadsheet.
|
8
|
+
|
9
|
+
Implement a basic reactive system with cells with settable values ("input"
|
10
|
+
cells) and cells with values computed in terms of other cells ("compute"
|
11
|
+
cells). Implement updates so that when an input value is changed, values
|
12
|
+
propagate to reach a new stable system state.
|
13
|
+
|
14
|
+
In addition, compute cells should allow for registering change notification
|
15
|
+
callbacks. Call a cell’s callbacks when the cell’s value in a new stable
|
16
|
+
state has changed from the previous stable state.
|
17
|
+
|
18
|
+
## Setup
|
19
|
+
|
20
|
+
Go through the setup instructions for ECMAScript to
|
21
|
+
install the necessary dependencies:
|
22
|
+
|
23
|
+
http://exercism.io/languages/ecmascript/installation
|
24
|
+
|
25
|
+
## Requirements
|
26
|
+
|
27
|
+
Install assignment dependencies:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
$ npm install
|
31
|
+
```
|
32
|
+
|
33
|
+
## Making the test suite pass
|
34
|
+
|
35
|
+
Execute the tests with:
|
36
|
+
|
37
|
+
```bash
|
38
|
+
$ npm test
|
39
|
+
```
|
40
|
+
|
41
|
+
In the test suites all tests but the first have been skipped.
|
@@ -0,0 +1,101 @@
|
|
1
|
+
class InputCell {
|
2
|
+
constructor(value) {
|
3
|
+
this.value = value;
|
4
|
+
this.updated = true;
|
5
|
+
this.subscribers = [];
|
6
|
+
}
|
7
|
+
|
8
|
+
setValue(value) {
|
9
|
+
if (value !== this.value) {
|
10
|
+
this.value = value;
|
11
|
+
this.notify();
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
notify() {
|
16
|
+
this.subscribers.forEach(sub => sub.markForUpdate());
|
17
|
+
this.subscribers.forEach(sub => sub.update());
|
18
|
+
}
|
19
|
+
|
20
|
+
addSubscriber(sub) {
|
21
|
+
this.subscribers.push(sub);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
class ComputeCell {
|
27
|
+
constructor(inputCells, fn) {
|
28
|
+
this.fn = fn;
|
29
|
+
this.inputCells = inputCells;
|
30
|
+
this.inputCells.forEach(cell => cell.addSubscriber(this));
|
31
|
+
this.subscribers = [];
|
32
|
+
this.value = fn(inputCells);
|
33
|
+
this.callbacks = [];
|
34
|
+
this.updated = true;
|
35
|
+
this.lastValue = this.value;
|
36
|
+
}
|
37
|
+
|
38
|
+
update() {
|
39
|
+
let value = this.fn(this.inputCells);
|
40
|
+
if (value !== this.value) {
|
41
|
+
this.value = value;
|
42
|
+
this.updated = true;
|
43
|
+
this.notify();
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
notify() {
|
48
|
+
this.subscribers.forEach(sub => sub.markForUpdate());
|
49
|
+
this.subscribers.forEach(sub => sub.update());
|
50
|
+
this.runCallbacks();
|
51
|
+
}
|
52
|
+
|
53
|
+
markForUpdate() {
|
54
|
+
this.updated = false;
|
55
|
+
this.subscribers.forEach(sub => sub.markForUpdate());
|
56
|
+
}
|
57
|
+
|
58
|
+
runCallbacks() {
|
59
|
+
if (this.allInputsUpdated() && this.valueChanged()) {
|
60
|
+
this.lastValue = this.value;
|
61
|
+
this.callbacks.forEach(cb => cb.run(this));
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
allInputsUpdated() {
|
66
|
+
return this.inputCells
|
67
|
+
.filter(cell => cell.updated)
|
68
|
+
.length === this.inputCells.length;
|
69
|
+
}
|
70
|
+
|
71
|
+
valueChanged() {
|
72
|
+
return this.lastValue !== this.value;
|
73
|
+
}
|
74
|
+
|
75
|
+
addSubscriber(sub) {
|
76
|
+
this.subscribers.push(sub);
|
77
|
+
}
|
78
|
+
|
79
|
+
addCallback(cb) {
|
80
|
+
this.callbacks.push(cb);
|
81
|
+
}
|
82
|
+
|
83
|
+
removeCallback(cb) {
|
84
|
+
this.callbacks = this.callbacks.filter(c => c !== cb);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
class CallbackCell {
|
90
|
+
constructor(fn) {
|
91
|
+
this.fn = fn;
|
92
|
+
this.values = [];
|
93
|
+
}
|
94
|
+
|
95
|
+
run(cell) {
|
96
|
+
this.values.push(this.fn(cell));
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
|
101
|
+
export {InputCell, ComputeCell, CallbackCell}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
{
|
2
|
+
"name": "xecmascript",
|
3
|
+
"version": "0.0.0",
|
4
|
+
"description": "Exercism exercises in ECMAScript 6.",
|
5
|
+
"author": "Katrina Owen",
|
6
|
+
"private": true,
|
7
|
+
"repository": {
|
8
|
+
"type": "git",
|
9
|
+
"url": "https://github.com/exercism/xecmascript"
|
10
|
+
},
|
11
|
+
"devDependencies": {
|
12
|
+
"babel-jest": "^21.2.0",
|
13
|
+
"babel-plugin-transform-builtin-extend": "^1.1.2",
|
14
|
+
"babel-preset-env": "^1.4.0",
|
15
|
+
"eslint": "^3.19.0",
|
16
|
+
"eslint-config-airbnb": "^15.0.1",
|
17
|
+
"eslint-plugin-import": "^2.2.0",
|
18
|
+
"eslint-plugin-jsx-a11y": "^5.0.1",
|
19
|
+
"eslint-plugin-react": "^7.0.1",
|
20
|
+
"jest": "^21.2.1"
|
21
|
+
},
|
22
|
+
"jest": {
|
23
|
+
"modulePathIgnorePatterns": [
|
24
|
+
"package.json"
|
25
|
+
]
|
26
|
+
},
|
27
|
+
"babel": {
|
28
|
+
"presets": [
|
29
|
+
"env"
|
30
|
+
],
|
31
|
+
"plugins": [
|
32
|
+
[
|
33
|
+
"babel-plugin-transform-builtin-extend",
|
34
|
+
{
|
35
|
+
"globals": [
|
36
|
+
"Error"
|
37
|
+
]
|
38
|
+
}
|
39
|
+
],
|
40
|
+
[
|
41
|
+
"transform-regenerator"
|
42
|
+
]
|
43
|
+
]
|
44
|
+
},
|
45
|
+
"scripts": {
|
46
|
+
"test": "jest --no-cache ./*",
|
47
|
+
"watch": "jest --no-cache --watch ./*",
|
48
|
+
"lint": "eslint .",
|
49
|
+
"lint-test": "eslint . && jest --no-cache ./* "
|
50
|
+
},
|
51
|
+
"eslintConfig": {
|
52
|
+
"parserOptions": {
|
53
|
+
"ecmaVersion": 6,
|
54
|
+
"sourceType": "module"
|
55
|
+
},
|
56
|
+
"env": {
|
57
|
+
"es6": true,
|
58
|
+
"node": true,
|
59
|
+
"jest": true
|
60
|
+
},
|
61
|
+
"extends": "airbnb",
|
62
|
+
"rules": {
|
63
|
+
"import/no-unresolved": "off",
|
64
|
+
"import/extensions": "off"
|
65
|
+
}
|
66
|
+
},
|
67
|
+
"licenses": [
|
68
|
+
"MIT"
|
69
|
+
],
|
70
|
+
"dependencies": {}
|
71
|
+
}
|
@@ -0,0 +1,211 @@
|
|
1
|
+
import {InputCell, ComputeCell, CallbackCell} from './react';
|
2
|
+
|
3
|
+
describe('React module', () => {
|
4
|
+
|
5
|
+
test('accepts input', () => {
|
6
|
+
const inputCell = new InputCell(10);
|
7
|
+
expect(inputCell.value).toEqual(10);
|
8
|
+
});
|
9
|
+
|
10
|
+
xtest('allows input cell value to be set', () => {
|
11
|
+
const inputCell = new InputCell(4);
|
12
|
+
inputCell.setValue(20);
|
13
|
+
expect(inputCell.value).toEqual(20);
|
14
|
+
});
|
15
|
+
|
16
|
+
xtest('allows setting compute cells', () => {
|
17
|
+
const inputCell = new InputCell(1);
|
18
|
+
const fn = inputCells => inputCells[0].value + 1;
|
19
|
+
const computeCell = new ComputeCell([inputCell], fn);
|
20
|
+
expect(computeCell.value).toEqual(2);
|
21
|
+
});
|
22
|
+
|
23
|
+
xtest('compute cell takes inputs in correct order', () => {
|
24
|
+
const inputCells = [
|
25
|
+
new InputCell(1),
|
26
|
+
new InputCell(2)
|
27
|
+
];
|
28
|
+
|
29
|
+
const computeCell = new ComputeCell(
|
30
|
+
inputCells,
|
31
|
+
inputs => inputs[0].value + inputs[1].value * 10
|
32
|
+
);
|
33
|
+
|
34
|
+
expect(computeCell.value).toEqual(21);
|
35
|
+
});
|
36
|
+
|
37
|
+
xtest('compute cells update value when inputs are changed', () => {
|
38
|
+
const inputCell = new InputCell(1);
|
39
|
+
const computeCell = new ComputeCell(
|
40
|
+
[inputCell],
|
41
|
+
inputs => inputs[0].value + 1
|
42
|
+
);
|
43
|
+
inputCell.setValue(3);
|
44
|
+
expect(computeCell.value).toEqual(4);
|
45
|
+
});
|
46
|
+
|
47
|
+
|
48
|
+
xtest('compute cells can depend on other compute cells', () => {
|
49
|
+
const inputCell = new InputCell(1);
|
50
|
+
const timesTwo = new ComputeCell(
|
51
|
+
[inputCell],
|
52
|
+
inputs => inputs[0].value * 2
|
53
|
+
);
|
54
|
+
|
55
|
+
const timesThirty = new ComputeCell(
|
56
|
+
[inputCell],
|
57
|
+
inputs => inputs[0].value * 30
|
58
|
+
);
|
59
|
+
|
60
|
+
const sum = new ComputeCell(
|
61
|
+
[timesTwo, timesThirty],
|
62
|
+
inputs => inputs[0].value + inputs[1].value
|
63
|
+
);
|
64
|
+
|
65
|
+
expect(sum.value).toEqual(32);
|
66
|
+
|
67
|
+
inputCell.setValue(3);
|
68
|
+
expect(sum.value).toEqual(96);
|
69
|
+
});
|
70
|
+
|
71
|
+
xtest('compute cells fire callbacks', () => {
|
72
|
+
const inputCell = new InputCell(1);
|
73
|
+
const output = new ComputeCell(
|
74
|
+
[inputCell],
|
75
|
+
inputs => inputs[0].value + 1
|
76
|
+
);
|
77
|
+
|
78
|
+
const callback = new CallbackCell(cell => cell.value);
|
79
|
+
output.addCallback(callback);
|
80
|
+
|
81
|
+
inputCell.setValue(3);
|
82
|
+
expect(callback.values).toEqual([4]);
|
83
|
+
});
|
84
|
+
|
85
|
+
xtest('callbacks fire only when output values change', () => {
|
86
|
+
const inputCell = new InputCell(1);
|
87
|
+
const output = new ComputeCell(
|
88
|
+
[inputCell],
|
89
|
+
inputs => inputs[0].value < 3 ? 111 : 222
|
90
|
+
);
|
91
|
+
|
92
|
+
const callback = new CallbackCell(cell => cell.value);
|
93
|
+
output.addCallback(callback);
|
94
|
+
|
95
|
+
inputCell.setValue(2);
|
96
|
+
expect(callback.values).toEqual([]);
|
97
|
+
|
98
|
+
inputCell.setValue(4);
|
99
|
+
expect(callback.values).toEqual([222]);
|
100
|
+
});
|
101
|
+
|
102
|
+
|
103
|
+
xtest('callbacks can be added and removed', () => {
|
104
|
+
const inputCell = new InputCell(1);
|
105
|
+
const output = new ComputeCell(
|
106
|
+
[inputCell],
|
107
|
+
inputs => inputs[0].value + 1
|
108
|
+
);
|
109
|
+
|
110
|
+
const callback1 = new CallbackCell(cell => cell.value);
|
111
|
+
const callback2 = new CallbackCell(cell => cell.value);
|
112
|
+
|
113
|
+
output.addCallback(callback1);
|
114
|
+
output.addCallback(callback2);
|
115
|
+
|
116
|
+
inputCell.setValue(31);
|
117
|
+
|
118
|
+
output.removeCallback(callback1);
|
119
|
+
|
120
|
+
const callback3 = new CallbackCell(cell => cell.value);
|
121
|
+
output.addCallback(callback3);
|
122
|
+
|
123
|
+
inputCell.setValue(41);
|
124
|
+
|
125
|
+
expect(callback1.values).toEqual([32]);
|
126
|
+
expect(callback2.values).toEqual([32, 42]);
|
127
|
+
expect(callback3.values).toEqual([42]);
|
128
|
+
});
|
129
|
+
|
130
|
+
xtest('removing a callback multiple times doesn\'t interfere with other callbacks', () => {
|
131
|
+
const inputCell = new InputCell(1);
|
132
|
+
const output = new ComputeCell(
|
133
|
+
[inputCell],
|
134
|
+
inputs => inputs[0].value + 1
|
135
|
+
);
|
136
|
+
|
137
|
+
const callback1 = new CallbackCell(cell => cell.value);
|
138
|
+
const callback2 = new CallbackCell(cell => cell.value);
|
139
|
+
|
140
|
+
output.addCallback(callback1);
|
141
|
+
output.addCallback(callback2);
|
142
|
+
|
143
|
+
output.removeCallback(callback1);
|
144
|
+
output.removeCallback(callback1);
|
145
|
+
output.removeCallback(callback1);
|
146
|
+
|
147
|
+
inputCell.setValue(2);
|
148
|
+
|
149
|
+
expect(callback1.values).toEqual([]);
|
150
|
+
expect(callback2.values).toEqual([3]);
|
151
|
+
});
|
152
|
+
|
153
|
+
xtest('callbacks should only be called once, even if multiple dependencies change', () => {
|
154
|
+
const inputCell = new InputCell(1);
|
155
|
+
const plusOne = new ComputeCell(
|
156
|
+
[inputCell],
|
157
|
+
inputs => inputs[0].value + 1
|
158
|
+
);
|
159
|
+
|
160
|
+
const minusOne1 = new ComputeCell(
|
161
|
+
[inputCell],
|
162
|
+
inputs => inputs[0].value - 1
|
163
|
+
);
|
164
|
+
|
165
|
+
const minusOne2 = new ComputeCell(
|
166
|
+
[minusOne1],
|
167
|
+
inputs => inputs[0].value - 1
|
168
|
+
);
|
169
|
+
|
170
|
+
const output = new ComputeCell(
|
171
|
+
[plusOne, minusOne2],
|
172
|
+
inputs => inputs[0].value * inputs[1].value
|
173
|
+
);
|
174
|
+
|
175
|
+
const callback1 = new CallbackCell(cell => cell.value);
|
176
|
+
output.addCallback(callback1);
|
177
|
+
|
178
|
+
inputCell.setValue(4);
|
179
|
+
|
180
|
+
expect(callback1.values).toEqual([10]);
|
181
|
+
});
|
182
|
+
|
183
|
+
xtest('callbacks should not be called if dependencies change but output value doesn\'t change', () => {
|
184
|
+
const inputCell = new InputCell(1);
|
185
|
+
const plusOne = new ComputeCell(
|
186
|
+
[inputCell],
|
187
|
+
inputs => inputs[0].value + 1
|
188
|
+
);
|
189
|
+
|
190
|
+
const minusOne = new ComputeCell(
|
191
|
+
[inputCell],
|
192
|
+
inputs => inputs[0].value - 1
|
193
|
+
);
|
194
|
+
|
195
|
+
const alwaysTwo = new ComputeCell(
|
196
|
+
[plusOne, minusOne],
|
197
|
+
inputs => inputs[0].value - inputs[1].value
|
198
|
+
);
|
199
|
+
|
200
|
+
|
201
|
+
const callback = new CallbackCell(cell => cell.value);
|
202
|
+
alwaysTwo.addCallback(callback);
|
203
|
+
|
204
|
+
inputCell.setValue(2);
|
205
|
+
inputCell.setValue(3);
|
206
|
+
inputCell.setValue(4);
|
207
|
+
inputCell.setValue(5);
|
208
|
+
|
209
|
+
expect(callback.values).toEqual([]);
|
210
|
+
});
|
211
|
+
});
|