Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 09e7bf6

Browse files
authored
Merge pull request #19 from dwyl/address-rjmk-comments
Address Review Comments
2 parents 7d280a8 + acb9f60 commit 09e7bf6

File tree

11 files changed

+245
-95
lines changed

11 files changed

+245
-95
lines changed

‎.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
node_js:
3+
- 6
4+
before_install:
5+
- pip install --user codecov
6+
after_success:
7+
- codecov --file coverage/lcov.info --disable search

‎README.md

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
Learn how to build web applications using
44
the Elm ("Model Update View") Architecture in "_plain_" JavaScript.
55

6+
[![Build Status](https://travis-ci.org/dwyl/learn-elm-architecture-in-javascript.svg?branch=master)](https://travis-ci.org/dwyl/learn-elm-architecture-in-javascript)
7+
[![codecov](https://codecov.io/gh/dwyl/learn-elm-architecture-in-javascript/branch/master/graph/badge.svg)](https://codecov.io/gh/dwyl/learn-elm-architecture-in-javascript)
8+
[![dependencies Status](https://david-dm.org/dwyl/learn-elm-architecture-in-javascript/status.svg)](https://david-dm.org/dwyl/learn-elm-architecture-in-javascript)
9+
[![devDependencies Status](https://david-dm.org/dwyl/learn-elm-architecture-in-javascript/dev-status.svg)](https://david-dm.org/dwyl/learn-elm-architecture-in-javascript?type=dev)
10+
11+
612
> We think Elm is the _future_ of Front End Web Development <br />
713
for all the _reasons_ described in:
814
[github.com/dwyl/**learn-elm#why**](https://github.com/dwyl/learn-elm#why) <br />
@@ -53,7 +59,7 @@ When compared to _other_ ways of organizing your code,
5359
"MUV" has the following benefits:
5460
+ Easier to _understand_ what is going on in more advanced apps
5561
because the "_flow_" is always the same.
56-
+ ***Uni-directional data-flow*** means "state" is always predictable:
62+
+ ***Uni-directional data-flow*** means "state" of the app is always predictable;
5763
given a specific starting "state" and sequence of update actions
5864
the output/end state will _always_ be the same. This makes testing/testability
5965
very easy!
@@ -68,7 +74,7 @@ very easy!
6874

6975
Anyone who knows a _little_ bit of JavaScript
7076
and wants to learn how to organize/structure <br />
71-
their code/app in the most _sane_, predictable and testable way.
77+
their code/app in a _sane_, predictable and testable way.
7278

7379
### _Prerequisites_?
7480

@@ -99,7 +105,7 @@ is often referred to as the application's `state`
99105
+ **U**pdate - how your app handles `actions` performed
100106
by people and `update` the `state` of your.
101107
+ **V**iew - what the people using your app can see;
102-
a way to `view` your state as `HTML`
108+
a way to `view` the Model (counter) as `HTML`
103109

104110
![elm-muv-architecture-diagram](https://cloud.githubusercontent.com/assets/194400/25773775/b6a4b850-327b-11e7-9857-79b6972b49c3.png)
105111

@@ -166,24 +172,21 @@ The mount function "wires up" the app and tells the _view_
166172
how to process a `signal` sent by the user/client.
167173

168174
```js
169-
// Mount Function receives all MUV and mounts the app in the "root" node
170-
function mount(muv, id) { // state is encapsulated by mount function
171-
var root = document.getElementById(id); // get ref to root DOM element once
172-
var update = muv.update; // make local copies of the init parameters
173-
var state = muv.model; // initial state
174-
var view = muv.view; // view is what renders the UI in Browser
175-
175+
function mount(model, update, view, root_element_id) {
176+
var root = document.getElementById(root_element_id); // root DOM element
176177
function signal(action) { // signal function takes action
177178
return function callback() { // and returns callback
178-
state = update(state, action); // update state according to action
179-
view(signal, state, root); // subsequent re-rendering
179+
model = update(model, action); // update model according to action
180+
view(signal, model, root); // subsequent re-rendering
180181
};
181182
};
182-
view(signal, state, root); // render initial state (once)
183+
view(signal, model, root); // render initial model (once)
183184
}
184185
```
186+
185187
`mount` receives an `Object` containing three properties:
186-
+ `model`: "_initial state_" of your application.
188+
+ `model`: "_initial state_" of your application
189+
(_in this case the counter which starts at 0_)
187190
+ `update`: the function that gets executed when ever a "_signal_"
188191
is received from the client (_person using the app_).
189192
+ `view`: the function that renders the DOM (_see: section 5.3 below_)
@@ -247,7 +250,7 @@ or you want _more_ detail/examples,
247250
#### 5.1.1 `mount` > render initial view
248251

249252
The last line in the `mount` function is to _render_ the `view` function
250-
for the first time passing in the `signal` function, initial state
253+
for the first time passing in the `signal` function, initial model ("state")
251254
and root element. This is the _initial_ rendering of the UI.
252255

253256

@@ -283,11 +286,11 @@ to the required function for processing.
283286

284287
In the case of our simple counter we aren't defining functions for each `case`:
285288
```js
286-
function update(model, action) { // Update function takes the current state
289+
function update(model, action) { // Update function takes the current model
287290
switch(action) { // and an action (String) runs a switch
288291
case Inc: return model + 1; // add 1 to the model
289292
case Dec: return model - 1; // subtract 1 from model
290-
default: return model; // if no action, return curent state.
293+
default: return model; // if no action, return current model.
291294
} // (default action always returns current)
292295
}
293296
```
@@ -333,7 +336,7 @@ function view(signal, model, root) {
333336
The `view` receives three arguments:
334337
+ `signal` defined above in `mount` (_above_) tells each (DOM) element
335338
how to to "handle" the user input.
336-
+ `model` a reference to the current state of the application.
339+
+ `model` a reference to the _current_ value of the counter.
337340
+ `root` a reference to the root DOM element where the app is _mounted_.
338341

339342
The `view` function starts by _emptying_
@@ -636,7 +639,7 @@ test('reset button should be present on page', function(assert) {
636639
assert.equal(reset.length, 1);
637640
});
638641
639-
test('Click reset button resets state to 0', function(assert) {
642+
test('Click reset button resets model (counter) to 0', function(assert) {
640643
mount({model: 7, update: update, view: view}, id); // set initial state
641644
var root = document.getElementById(id);
642645
assert.equal(root.getElementsByClassName('count')[0].textContent, 7);

‎examples/counter-basic-test/counter.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
// Mount Function receives all the elements and mounts the app
2-
function mount(muv, id) { // state is encapsulated by mount function
3-
var root = document.getElementById(id);
4-
var update = muv.update; // make local copies of the init parameters
5-
var state = muv.model; // initial state
6-
var view = muv.view; // view is what renders the UI in Browser
7-
8-
function signal(action) { // signal function takes action
9-
return function callback() { // and returns callback
10-
state = update(state, action); // update state according to action
11-
view(signal, state, root); // subsequent re-rendering
12-
};
13-
};
14-
view(signal, state, root); // render initial state (once)
15-
}
161
// Define the Component's Actions:
172
var Inc = 'inc'; // increment the counter
183
var Dec = 'dec'; // decrement the counter
@@ -34,6 +19,18 @@ function view(signal, model, root) {
3419
].forEach(function(el){ root.appendChild(el) }); // forEach is ES5 so IE9+
3520
} // yes, for loop is "faster" than forEach, but readability trumps "perf" here!
3621

22+
// Mount Function receives all MUV and mounts the app in the "root" DOM Element
23+
function mount(model, update, view, root_element_id) {
24+
var root = document.getElementById(root_element_id); // root DOM element
25+
function signal(action) { // signal function takes action
26+
return function callback() { // and returns callback
27+
model = update(model, action); // update model according to action
28+
view(signal, model, root); // subsequent re-rendering
29+
};
30+
};
31+
view(signal, model, root); // render initial model (once)
32+
}
33+
3734
// The following are "Helper" Functions which each "Do ONLY One Thing" and are
3835
// used in the "View" function to render the Model (State) to the Browser DOM:
3936

@@ -56,6 +53,7 @@ function button(text, signal, action) {
5653
function div(divid, text) {
5754
var div = document.createElement('div');
5855
div.id = divid;
56+
div.className = divid;
5957
if(text !== undefined) { // if text is passed in render it in a "Text Node"
6058
var txt = document.createTextNode(text);
6159
div.appendChild(txt);

‎examples/counter-basic-test/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<script src="counter.js" data-cover></script> <!-- load counter -->
1616
<script>
1717
// Initialise the app by "mounting" it passing in MUV Object & "root" DOM node
18-
mount({model: 0, update, view}, 'app');
18+
mount(0, update, view, 'app');
1919
</script>
2020

2121
<!-- Below this point is all related to the Tests for the App -->

‎examples/counter-basic-test/test.js

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var id = 'test-app'
1+
var id = 'test-app';
22

33
test('Test Update update(0) returns 0 (current state)', function(assert) {
44
var result = update(0);
@@ -20,30 +20,27 @@ test('Test negative state: update(-9, "inc") returns -8', function(assert) {
2020
assert.equal(result, -8);
2121
});
2222

23-
test('mount({model: 7, update: update, view: view}, "'
24-
+ id +'") sets initial state to 7', function(assert) {
25-
var init = {model: 7, update: update, view: view};
26-
mount(init, id);
23+
test('mount({model: 9, update: update, view: view}, "'
24+
+ id +'") sets initial state to 9', function(assert) {
25+
mount(9, update, view, id);
2726
var state = document.getElementById(id).textContent.replace(/-+/, '');
28-
assert.equal(state, 7);
27+
assert.equal(state, 9);
2928
});
3029

3130
test('empty("test-app") should clear DOM in root node', function(assert) {
3231
empty(document.getElementById(id));
33-
var init = {model: 7, update: update, view: view};
34-
mount(init, id);
32+
mount(7, update, view, id);
3533
empty(document.getElementById(id));
3634
var result = document.getElementById(id).innerHtml
3735
assert.equal(result, undefined);
3836
});
3937

4038
test('click on "+" button to re-render state (increment model by 1)',
4139
function(assert) {
42-
document.body.appendChild(div(id));
43-
var init = {model: 7, update: update, view: view};
44-
mount(init, id);
45-
document.getElementsByTagName('button')[2].click(); // there are 4 buttons
46-
var state = document.getElementById(id).textContent.replace(/-+/, '');
40+
mount(7, update, view, id);
41+
document.getElementById(id).getElementsByClassName('inc')[0].click();
42+
var state = document.getElementById(id)
43+
.getElementsByClassName('count')[0].textContent;
4744
assert.equal(state, 8); // model was incremented successfully
48-
empty(document.getElementById(id));// clean up after tests
45+
empty(document.getElementById(id));
4946
});

‎examples/counter-basic/index.html

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
function div(divid, text) {
2828
var div = document.createElement('div');
2929
div.id = divid;
30+
div.className = divid; // use divid as CSS class name
3031
if(text !== undefined) { // if text is passed in render it in a "Text Node"
3132
var txt = document.createTextNode(text);
3233
div.appendChild(txt);
@@ -44,45 +45,41 @@
4445
} // how to create a button in JavaScript: stackoverflow.com/a/8650996/1148249
4546

4647
// HERE Begins the App and Your Adventure into the Elm Architecture! ;-)
47-
48-
// Mount Function receives all MUV and mounts the app in the "root" node
49-
function mount(muv, id) { // state is encapsulated by mount function
50-
var root = document.getElementById(id); // get ref to root DOM element once
51-
var update = muv.update; // make local copies of the init parameters
52-
var state = muv.model; // initial state
53-
var view = muv.view; // view is what renders the UI in Browser
54-
55-
function signal(action) { // signal function takes action
56-
return function callback() { // and returns callback
57-
state = update(state, action); // update state according to action
58-
view(signal, state, root); // subsequent re-rendering
59-
};
60-
};
61-
view(signal, state, root); // render initial state (once)
62-
}
6348
// Define the Component's Actions:
6449
var Inc = 'inc'; // increment the counter
6550
var Dec = 'dec'; // decrement the counter
6651

67-
function update(model, action) { // Update function takes the current state
52+
function update(model, action) { // Update function takes the current model
6853
switch(action) { // and an action (String) runs a switch
6954
case Inc: return model + 1; // add 1 to the model
7055
case Dec: return model - 1; // subtract 1 from model
71-
default: return model; // if no action, return curent state.
56+
default: return model; // if no action, return curent model.
7257
} // (default action always returns current)
7358
}
7459

7560
function view(signal, model, root) {
7661
empty(root); // clear root element before
7762
[ // Store DOM nodes in an array
7863
button('+', signal, Inc), // create button (defined below)
79-
div('count', model), // show the "state" of the Model
64+
div('count', model), // display the "state" of Model
8065
button('-', signal, Dec) // button to decrement counter
8166
].forEach(function(el){ root.appendChild(el) }); // forEach is ES5 so IE9+
8267
} // yes, for loop is "faster" than forEach, but readability trumps "perf" here!
8368

69+
// Mount Function receives all MUV and mounts the app in the "root" DOM Element
70+
function mount(model, update, view, root_element_id) {
71+
var root = document.getElementById(root_element_id); // root DOM element
72+
function signal(action) { // signal function takes action
73+
return function callback() { // and returns callback
74+
model = update(model, action); // update model according to action
75+
view(signal, model, root); // subsequent re-rendering
76+
};
77+
};
78+
view(signal, model, root); // render initial model (once)
79+
}
80+
8481
// Initialise the app by "mounting" it passing in MUV Object and "root" DOM node
85-
mount({model: 0, update, view}, 'app');
82+
mount(0, update, view, 'app');
8683
</script>
8784

8885
<!-- Below this point is all related to the Tests for the App -->

‎examples/counter-reset/counter.js

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
// Mount Function receives all the elements and mounts the app
2-
function mount(muv, id) { // state is encapsulated by mount function
3-
var root = document.getElementById(id);
4-
var update = muv.update; // make local copies of the init parameters
5-
var state = muv.model; // initial state
6-
var view = muv.view; // view is what renders the UI in Browser
7-
8-
function signal(action) { // signal function takes action
9-
return function callback() { // and returns callback
10-
state = update(state, action); // update state according to action
11-
view(signal, state, root); // subsequent re-rendering
12-
};
13-
};
14-
view(signal, state, root); // render initial state (once)
15-
}
161
// Define the Component's Actions:
172
var Inc = 'inc'; // increment the counter
183
var Dec = 'dec'; // decrement the counter
@@ -37,6 +22,17 @@ function view(signal, model, root) {
3722
].forEach(function(el){ root.appendChild(el) }); // forEach is ES5 so IE9+
3823
} // yes, for loop is "faster" than forEach, but readability trumps "perf" here!
3924

25+
// Mount Function receives all MUV and mounts the app in the "root" DOM Element
26+
function mount(model, update, view, root_element_id) {
27+
var root = document.getElementById(root_element_id); // root DOM element
28+
function signal(action) { // signal function takes action
29+
return function callback() { // and returns callback
30+
model = update(model, action); // update model according to action
31+
view(signal, model, root); // subsequent re-rendering
32+
};
33+
};
34+
view(signal, model, root); // render initial model (once)
35+
}
4036

4137
// The following are "Helper" Functions which each "Do ONLY One Thing" and are
4238
// used in the "View" function to render the Model (State) to the Browser DOM:
@@ -53,6 +49,7 @@ function button(text, signal, action) {
5349
var text = document.createTextNode(text); // human-readable button text
5450
button.appendChild(text); // text goes *inside* not attrib
5551
button.className = action; // use action as CSS class
52+
button.id = action;
5653
// console.log(signal, ' action:', action)
5754
button.onclick = signal(action); // onclick tells how to process
5855
return button; // return the DOM node(s)
@@ -68,3 +65,20 @@ function div(divid, text) {
6865
}
6966
return div;
7067
}
68+
69+
function init(doc){
70+
document = doc; // this is used for instantiating JSDOM. ignore!
71+
}
72+
73+
/* The code block below ONLY Applies to tests run using Node.js */
74+
/* istanbul ignore next */
75+
if (typeof module !== 'undefined' && module.exports) { module.exports = {
76+
view: view,
77+
mount: mount,
78+
update: update,
79+
div: div,
80+
button: button,
81+
empty: empty,
82+
init: init
83+
}
84+
} else { init(document); }

‎examples/counter-reset/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<script src="counter.js" data-cover></script> <!-- load counter -->
1616
<script>
1717
// Initialise the app by "mounting" it passing in MUV Object & "root" DOM node
18-
mount({model: 0, update, view}, 'app');
18+
mount(0, update, view, 'app');
1919
</script>
2020

2121
<!-- Below this point is all related to the Tests for the App -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /