-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adds counter reset example with failing test #5 (comment)
- Loading branch information
Showing
5 changed files
with
253 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Mount Function receives all the elements and mounts the app | ||
function mount(muv, id) { // state is encapsulated by mount function | ||
var root = document.getElementById(id); | ||
var update = muv.update; // make local copies of the init parameters | ||
var state = muv.model; // initial state | ||
var view = muv.view; // view is what renders the UI in Browser | ||
|
||
function signal(action) { // signal function takes action | ||
return function callback() { // and returns callback | ||
state = update(state, action); // update state according to action | ||
view(signal, state, root); // subsequent re-rendering | ||
}; | ||
}; | ||
view(signal, state, root); // render initial state (once) | ||
} | ||
// Define the Component's Actions: | ||
var Inc = 'inc'; // increment the counter | ||
var Dec = 'dec'; // decrement the counter | ||
|
||
|
||
function update(model, action) { // Update function takes the current state | ||
switch(action) { // and an action (String) runs a switch | ||
case Inc: return model + 1; // add 1 to the model | ||
case Dec: return model - 1; // subtract 1 from model | ||
default: return model; // if no action, return curent state. | ||
} // (default action always returns current) | ||
} | ||
|
||
function view(signal, model, root) { | ||
empty(root); // clear root element before | ||
return [ // Store DOM nodes in an array | ||
button('+', signal, Inc), // then iterate to append them | ||
div('count', model), // avoids repetition. | ||
button('-', signal, Dec) | ||
].forEach(function(el){ root.appendChild(el) }); // forEach is ES5 so IE9+ | ||
} // yes, for loop is "faster" than forEach, but readability trumps "perf" here! | ||
|
||
// The following are "Helper" Functions which each "Do ONLY One Thing" and are | ||
// used in the "View" function to render the Model (State) to the Browser DOM: | ||
|
||
// empty the contents of a given DOM element "node" (before re-rendering) | ||
function empty(node) { | ||
while (node.firstChild) { | ||
node.removeChild(node.firstChild); | ||
} | ||
} // Inspired by: stackoverflow.com/a/3955238/1148249 | ||
|
||
function button(text, signal, action) { | ||
var button = document.createElement('button'); | ||
var text = document.createTextNode(text); // human-readable button text | ||
button.appendChild(text); // text goes *inside* not attrib | ||
button.className = action; // use action as CSS class | ||
button.onclick = signal(action); // onclick tells how to process | ||
return button; // return the DOM node(s) | ||
} // how to create a button in JavaScript: stackoverflow.com/a/8650996/1148249 | ||
|
||
function div(divid, text) { | ||
var div = document.createElement('div'); | ||
div.id = divid; | ||
if(text !== undefined) { // if text is passed in render it in a "Text Node" | ||
var txt = document.createTextNode(text); | ||
div.appendChild(txt); | ||
} | ||
return div; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<!DOCTYPE html> | ||
<html lang=”en-GB”> | ||
<head> | ||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | ||
<meta name="viewport" | ||
content="width=device-width, initial-scale=1.0, user-scalable=yes"> | ||
<title>Elm Architecture in JS - Counter Reset</title> | ||
<link rel="shortcut icon" | ||
href="http://www.dwyl.io/images/favicon.ico" type="image/x-icon"> | ||
<!-- CSS Styles are 100% optional. but they make it look *much* nicer --> | ||
<link rel="stylesheet" href="../style.css"> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
<script src="counter.js" data-cover></script> <!-- load counter --> | ||
<script> | ||
// Initialise the app by "mounting" it passing in MUV Object & "root" DOM node | ||
mount({model: 0, update, view}, 'app'); | ||
</script> | ||
|
||
<!-- Below this point is all related to the Tests for the App --> | ||
<div id="test-app"></div> <!-- Create a test-app div to mount the app --> | ||
<div id="qunit"></div> <!-- test results are displayed here --> | ||
<!-- Load the QUnit CSS file from CDN - require to display our tests --> | ||
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.18.0.css"> | ||
<!-- Load the QUnit Testing Framework from CDN - to run the tests --> | ||
<script src="//code.jquery.com/qunit/qunit-1.18.0.js"></script> | ||
<!-- Load Blanket.js from CDN - for test coverage stats --> | ||
<script src="//cdnjs.cloudflare.com/ajax/libs/blanket.js/1.1.4/blanket.js"> | ||
</script> | ||
<script src="test.js"></script> <!-- always load test.js last --> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
var id = 'test-app' | ||
|
||
test('Test Update update(0) returns 0 (current state)', function(assert) { | ||
var result = update(0); | ||
assert.equal(result, 0); | ||
}); | ||
|
||
test('Test Update increment: update(1, "inc") returns 2', function(assert) { | ||
var result = update(1, "inc"); | ||
assert.equal(result, 2); | ||
}); | ||
|
||
test('Test Update decrement: update(3, "dec") returns 2', function(assert) { | ||
var result = update(1, "dec"); | ||
assert.equal(result, 0); | ||
}); | ||
|
||
test('Test negative state: update(-9, "inc") returns -8', function(assert) { | ||
var result = update(-9, "inc"); | ||
assert.equal(result, -8); | ||
}); | ||
|
||
test('mount({model: 7, update: update, view: view}, "' | ||
+ id +'") sets initial state to 7', function(assert) { | ||
var init = {model: 7, update: update, view: view}; | ||
mount(init, id); | ||
var state = document.getElementById(id).textContent.replace(/-+/, ''); | ||
assert.equal(state, 7); | ||
}); | ||
|
||
test('empty("test-app") should clear DOM in root node', function(assert) { | ||
empty(document.getElementById(id)); | ||
var init = {model: 7, update: update, view: view}; | ||
mount(init, id); | ||
empty(document.getElementById(id)); | ||
var result = document.getElementById(id).innerHtml | ||
assert.equal(result, undefined); | ||
}); | ||
|
||
test('click on "+" button to re-render state (increment model by 1)', | ||
function(assert) { | ||
document.body.appendChild(div(id)); | ||
var init = {model: 7, update: update, view: view}; | ||
mount(init, id); | ||
document.getElementsByTagName('button')[2].click(); // there are 4 buttons | ||
var state = document.getElementById(id).textContent.replace(/-+/, ''); | ||
assert.equal(state, 8); // model was incremented successfully | ||
empty(document.getElementById(id)); // clean up after tests | ||
}); | ||
|
||
test('Test reset counter when model/state is 6 returns 0', function(assert) { | ||
var result = update(6, "reset"); | ||
assert.equal(result, 0); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters