Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Elm(ish) Todo List (TodoMVC) Example issue #44 #45

Merged
merged 165 commits into from
Sep 8, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
165 commits
Select commit Hold shift + click to select a range
6db982a
create basic files for "elmish" Todo List #44
nelsonic Jul 5, 2018
cc1b8b8
adds todo-list.md (outline) for #44
nelsonic Jul 9, 2018
8908312
add base TodoMVC CSS file from https://github.com/tastejs/todomvc/tre…
nelsonic Jul 10, 2018
7813efd
adds complete TodoMVC requirements to todo-list.md for #44
nelsonic Jul 11, 2018
f6b7e6e
add link to todo-list.md in README.md #44
nelsonic Jul 11, 2018
45ece77
add sample html code for TodoMVC https://github.com/dwyl/learn-elm-ar…
nelsonic Jul 12, 2018
5451619
refactor counter-reset tests to use tape (cleaner)!
nelsonic Jul 13, 2018
94bbbbf
run tape tests in pre-commit and on CI (faster and simpler)
nelsonic Jul 13, 2018
8aafc99
add link to https://github.com/dwyl/learn-tape as using Tape in Todo …
nelsonic Jul 13, 2018
c5101d9
add empty function with JSDOC & test for #44
nelsonic Jul 14, 2018
08723c9
use jsdom-global instead of *manually* instantiating JSDOM! for #44
nelsonic Jul 14, 2018
eeec661
use view & update from counter-reset example to test elmish.mount gen…
nelsonic Jul 14, 2018
28ab679
add instructions for empty function in todo-list.md for #44
nelsonic Jul 14, 2018
560c9bc
adds instructions+code for mount generic function in elm(ish) for #44
nelsonic Jul 14, 2018
cb41458
add elmish.attributes function to apply HTML attributes to node for h…
nelsonic Jul 15, 2018
0b28eca
add id case to attributes function for #44
nelsonic Jul 15, 2018
41dd1a6
add package-lock.json to .gitignore #noise!
nelsonic Jul 15, 2018
21f05d5
add tap-spec to package.json and test script to "prettify" test outpu…
nelsonic Jul 15, 2018
25cd493
add instructions for elmish attributes function #44
nelsonic Jul 15, 2018
606e293
rename attributes to add_attributes for clarity! #44
nelsonic Jul 15, 2018
6763bae
adds elmish.append_children test, docs & function for #44
nelsonic Jul 15, 2018
ac5eeb3
rename to elmish.append_childnodes for clarity ... #44
nelsonic Jul 15, 2018
6a715fe
add Input Placeholder Attribute instructions, test and code for #44
nelsonic Jul 16, 2018
cfa2832
remove test.only to ensure all tests are executed
nelsonic Jul 16, 2018
536f2ec
add elmish.add_attributes set data-id on <li> element for #44
nelsonic Jul 16, 2018
906639e
adds <label for="toggle-all"> for #44
nelsonic Jul 16, 2018
511c868
update codecov script in .travis.yml (simplify)
nelsonic Jul 16, 2018
43bd3d6
add type attribute to <input> element e.g: <input id="toggle-all" typ…
nelsonic Jul 16, 2018
22c809b
adds instructions, docs, test and implementation for applying in-line…
nelsonic Jul 17, 2018
4b1e680
add instructions, docs, test & code for checked=true for #44
nelsonic Jul 18, 2018
6b6495a
add checked=false for toggling todo items
nelsonic Jul 18, 2018
111644e
add href attribute to <a> tags (Docs, Tests & Code) for #44
nelsonic Jul 19, 2018
a3a4bfa
add instructions, tests & code for <input autofocus> for #44
nelsonic Jul 19, 2018
48e1bb8
<input autofocus> unavailable on iOS Safari! https://caniuse.com/#fea…
nelsonic Jul 19, 2018
956ac1f
add test, JSDOC and implementation of <section> html element for #44
nelsonic Jul 19, 2018
6c66a04
adds create_element DOM element creation function to "DRY" DOM code f…
nelsonic Jul 19, 2018
59c5298
add <section> test code to todo-list.md for #44
nelsonic Jul 19, 2018
be35d3e
add two "compound" views, tests, docs & code to pass tests! (for #44)
nelsonic Jul 19, 2018
27ea95c
add remaining instructions/docs, tests & code for <footer> view! #44 …
nelsonic Jul 20, 2018
59664d9
adds example location.href and history.pushState code for https://git…
nelsonic Jul 21, 2018
fa20108
add JSDOC for elmish.route function for #46
nelsonic Jul 22, 2018
b22596e
add instructions test(s) and code for routing! closes #46
nelsonic Jul 22, 2018
a1a1e30
add intro text and sample code for saving Todo List data to localStor…
nelsonic Jul 22, 2018
8f34ff7
adds test for localStorage functionality #47 to todo-list.md
nelsonic Jul 22, 2018
fb83010
add test for Elm(ish) localStorage in mount function with implementat…
nelsonic Jul 22, 2018
e0d64de
remove localstorage-polyfil from package.json as not using
nelsonic Jul 22, 2018
e7d542f
adds "Acceptance Criteria" for localStorage functionality. closes #47
nelsonic Jul 22, 2018
c70ba2b
preparing to move elm(ish) code to elmish.md ... for #44
nelsonic Jul 23, 2018
47bb415
adds clarifying note on why "Elm(ish)" for #44
nelsonic Jul 24, 2018
208c153
add Elm(ish) intro header image to elmish.md for #44
nelsonic Jul 25, 2018
6fe6364
add What? Who? & How? sections to elmish.md for #44
nelsonic Jul 25, 2018
2b21e7a
Always imagine that you are "_pairing_" with someone
nelsonic Jul 26, 2018
f94ecd9
re-word Doc Driven Dev section
nelsonic Jul 27, 2018
42e0a4a
add instructsion for elmish.init function to elmish.md for #44
nelsonic Jul 28, 2018
7efdaf0
add screenshot of init + empty tests passing https://github.com/dwyl/…
nelsonic Jul 29, 2018
2e4622f
finish "transferring" the elm(ish) related code and docs to elmish.md…
nelsonic Jul 29, 2018
6898e8b
add link to /examples/multiple-counters-instances/index.html for #40 …
nelsonic Jul 30, 2018
075c4c4
minor markdown fixes for #44 https://youtu.be/E1vXNrN6BbU
nelsonic Jul 30, 2018
f9ba7aa
remove init function from counter-reset.js & counter-reset.test.js fi…
nelsonic Jul 30, 2018
6ec9868
remove init function from elmish.js & elmish.md see https://github.co…
nelsonic Jul 30, 2018
354685e
adds screenshots of tests failing & passing for add_attributes functi…
nelsonic Jul 30, 2018
5041de1
add further instructions & screenshots for placeholder attribute in e…
nelsonic Jul 30, 2018
81928f7
adds default branch test and pre-commit hook instructions to elmish.m…
nelsonic Jul 31, 2018
b1e3ecf
finish writeup of `Elm`(_ish_) for #44
nelsonic Jul 31, 2018
47caf12
add test setup lines to test/todo-app.test.js for #44
nelsonic Aug 1, 2018
0ff09c2
add sample `model` to todo-list.md for #44
nelsonic Aug 1, 2018
e1f9851
fix typo in elmish.md
nelsonic Aug 1, 2018
820250b
add section on learning style and three options for when people can r…
nelsonic Aug 1, 2018
39779b2
re-order params of update function in counter.js and elmish.js for cl…
nelsonic Aug 1, 2018
caf8165
[WiP] link back to Todo List from elmish.md & add `update` section fo…
nelsonic Aug 2, 2018
34c2a05
add code to pass default branch update test for #44
nelsonic Aug 2, 2018
23c9d47
ADD item acceptance criteria for https://github.com/dwyl/learn-elm-ar…
nelsonic Aug 3, 2018
dba0be7
add section on refactoring update JSDOC and function signature or #44…
nelsonic Aug 3, 2018
4571db0
add update ADD todo item test for #48
nelsonic Aug 3, 2018
a19da15
adds sample implementation for update ADD case for #48
nelsonic Aug 3, 2018
de9797e
finish writeup on ADD new todo item to list. #48
nelsonic Aug 4, 2018
5d4ebc5
add sample code for making TOGGLE todo item test pass for #48
nelsonic Aug 5, 2018
e29da0e
add writeup instructions for how to "undo" a todo item using TOGGLE a…
nelsonic Aug 5, 2018
ff4d297
adds section for creating the `view` for Elm(ish) Todo List App #44 /…
nelsonic Aug 5, 2018
afaed24
for now, ignore the <footer> and focus on rendering the Todo List! se…
nelsonic Aug 5, 2018
dd51dcb
add (human readable) Acceptance Criteria and Test Assertions for "mai…
nelsonic Aug 6, 2018
6137d41
[WiP] add test for "main" view #51
nelsonic Aug 6, 2018
91efbbd
add assertions to main view test for #51
nelsonic Aug 6, 2018
e7d6784
adds screenshot of failng test https://github.com/dwyl/learn-elm-arch…
nelsonic Aug 6, 2018
3cbb25b
add code to make render_item test pass see: https://github.com/dwyl/l…
nelsonic Aug 7, 2018
864f4cc
update test/elmish.test.js assertions in light of the removal of defa…
nelsonic Aug 7, 2018
b660747
add code to make render_main pass see/fixes #51
nelsonic Aug 7, 2018
82bd69d
remove (debuggin) console.log from render_item ... fix #52
nelsonic Aug 7, 2018
171f34a
add screenshot and text reminding readers that we have 100% test cove…
nelsonic Aug 7, 2018
8a50b25
add acceptance criteria for Todo List <footer> element https://github…
nelsonic Aug 7, 2018
8f2252a
add JSDOC comment for render_footer #53
nelsonic Aug 7, 2018
68e2afa
add render_footer function implementation for #53
nelsonic Aug 7, 2018
aae0490
adds JSDOC and test for view function #54
nelsonic Aug 7, 2018
3096d81
add view function implementation to pass tests for #54
nelsonic Aug 7, 2018
470ad9f
add link to reference implementation of view function fixes #54
nelsonic Aug 7, 2018
ef56c49
refactor counter-reset example to use the elmish mount function signa…
nelsonic Aug 8, 2018
93f00d0
add (failing) test and screenshot for "No Todos" test case #56
nelsonic Aug 8, 2018
d1bd85e
add code to pass test for "No Todos" fixes #56
nelsonic Aug 8, 2018
3b8eb11
add render function to DRY code in elmish mount function for #44 / #55
nelsonic Aug 9, 2018
a3cf67e
add test (failing) for "2. New Todo" #55
nelsonic Aug 9, 2018
260c104
add support for Subscritions in elmish.js for https://github.com/dwyl…
nelsonic Aug 9, 2018
c79eccf
add additional checks in Elmish/Todo-list App code for null values #44
nelsonic Aug 9, 2018
86dcc83
add extra keyCode "trigger" assertion to exercise subscrition branch #55
nelsonic Aug 9, 2018
7b56e55
update test for "2. New Todo" to test all branches
nelsonic Aug 9, 2018
f37c398
reorder New Todo test assertions for clarity #55
nelsonic Aug 9, 2018
d6c8b92
update examples/counter-reset/test.js to reflect change in parameter …
nelsonic Aug 10, 2018
e3e5a65
cp examples/counter-reset/* examples/counter-reset-keyboard/ for #57
nelsonic Aug 10, 2018
d890749
add test for onclick attribute for #57
nelsonic Aug 10, 2018
d41c8d8
add test and code for onclick function in attributes for/fixes #58
nelsonic Aug 10, 2018
7369443
add link to "solution" in onclick section of elmish.md
nelsonic Aug 10, 2018
209d72d
add sample code after refactoring counter-reset-keyboard to use Elm(i…
nelsonic Aug 10, 2018
a3e0644
fix failing test due to change in name of localstorage key for #57
nelsonic Aug 10, 2018
9a10d60
[WiP] elmish subscription test FAILING for #57
nelsonic Aug 10, 2018
39d270b
add additional assertions for counter-reset-keyboard example for #57
nelsonic Aug 10, 2018
0fd18b2
tidy-up counter-reset-keyboard example subscrition considerably! #57
nelsonic Aug 10, 2018
a326d58
update subscriptions parameter in elmish.mount for clarity fixe #57
nelsonic Aug 10, 2018
9471c34
add screenshot of counter-reset-keyboard subscription tests passing #57
nelsonic Aug 10, 2018
193d55e
add screenshot of 2. New Todo tests passing #57
nelsonic Aug 10, 2018
89de33a
add code to make TOGGLE_ALL tests pass. see/fixes https://github.com/…
nelsonic Aug 11, 2018
fff65da
add link to sample code for TOGGLE_ALL #50
nelsonic Aug 11, 2018
b8bb500
for some reason the class attribute *MUST* be last in array!
nelsonic Aug 11, 2018
b277b6c
add test (passing) for 4. Item (toggle) done #44
nelsonic Aug 11, 2018
a47b24c
[WiP] add outline of Acceptance Criteria for Editing a Todo List Item…
nelsonic Aug 11, 2018
aa4d787
Updates some typos and flow up until no. 7 of the basic counter #44
iteles Aug 12, 2018
77546af
add *failing* test for DELETE an item https://github.com/dwyl/learn-e…
nelsonic Sep 2, 2018
39ed374
implement DELETE todo item using least possible code. closes #59
nelsonic Sep 4, 2018
a597688
add acceptance criteria and checklist of features for EDIT todo item #60
nelsonic Sep 5, 2018
dbcca39
adds basic EDIT item implementation including EDIT and SAVE actions f…
nelsonic Sep 5, 2018
ce3258e
Merge pull request #61 from dwyl/review-todo
nelsonic Sep 5, 2018
72fd1a6
add link to StackOverflow answer for double-click function handler ht…
nelsonic Sep 5, 2018
43d2133
adds test for render_item in edit mode! #60
nelsonic Sep 6, 2018
fd60ff6
add screenshot of render_item ("edit mode") tests passing for #60
nelsonic Sep 6, 2018
0ffb30b
rename localStorage key prefix inline with TodoMVC spec: https://gith…
nelsonic Sep 6, 2018
c110c0c
add model.editing to sample model in examples/todo-list/index.html to…
nelsonic Sep 6, 2018
1a89e35
add code to to make EDIT case pass for #60
nelsonic Sep 6, 2018
2968cd8
add test for [ENTER] key in edit mode to SAVE revised todo item title…
nelsonic Sep 6, 2018
c8098e9
add SAVE todo item title edit implementation for #60
nelsonic Sep 6, 2018
eec3642
add test for SAVE *blank* todo title > should delete item for #60
nelsonic Sep 6, 2018
0887ba8
add implementation for SAVE *blank* item title > deletes item. #60
nelsonic Sep 6, 2018
4fdb098
add test for [esc] CANCEL ediing for #64
nelsonic Sep 6, 2018
d812e6c
add implementation for [esc] CANCEL editing fixes #64
nelsonic Sep 6, 2018
e367ce8
remove test.only ... derp!
nelsonic Sep 6, 2018
c40a583
add tests for 6, 7 & 8 for #48 (shift up a gear! time to get this don…
nelsonic Sep 7, 2018
b1f895b
update older tests to reflect clear-completed count in footer #48
nelsonic Sep 7, 2018
fc2ed3c
add test for routing based on clicking links in footer #48
nelsonic Sep 7, 2018
2e67605
add solution to routing all/active/completed using footer links inclu…
nelsonic Sep 7, 2018
f118ec4
add solution to routing all/active/completed using footer links inclu…
nelsonic Sep 7, 2018
812248b
first draft of TodoMVC tutorial *complete*!! :tada:
nelsonic Sep 7, 2018
9cabb38
remove port from npm start script to allow heroku to pass in PORT env…
nelsonic Sep 7, 2018
538d53a
comment out all console.log in todo-app.js to avoid noise ... un-comm…
nelsonic Sep 7, 2018
fcb0102
remove dev script from package.json as not needed/used
nelsonic Sep 7, 2018
31bb9bc
fix markdown fails in edit-todo.md
nelsonic Sep 7, 2018
e08461b
fix mixed content warning from loading dwyl favicon over http ... htt…
nelsonic Sep 7, 2018
607f004
add favicon.ico to examples/todo-list to avoid https://github.com/dwy…
nelsonic Sep 7, 2018
cd70fad
reference favicon.ico in todo-list/index.html for https://github.com/…
nelsonic Sep 7, 2018
ae61175
add link to https://todomvc-app.herokuapp.com/examples/todo-list in r…
nelsonic Sep 7, 2018
a5df3c4
add space between learning styles in todo-list.md
nelsonic Sep 7, 2018
1002ef5
"as a friend" >> "ask a friend" (correct typo!)
nelsonic Sep 7, 2018
b8f3ae9
add links to lower order rendering function issues to show workflow #…
nelsonic Sep 7, 2018
913b4d5
move edit-todo.md to todo-list.md (consolidate)
nelsonic Sep 7, 2018
a72ce67
remove edit-todo.md ... copy/code is in todo-list.md
nelsonic Sep 7, 2018
21e74f6
recommend reading https://github.com/dwyl/learn-heroku to deploy your…
nelsonic Sep 7, 2018
26e661e
add hyperlink to implementation of DELETE update case: https://github…
nelsonic Sep 7, 2018
ee9c95d
expand section 9 to explain the code a bit better ... #60
nelsonic Sep 8, 2018
f986777
add extended explanation of non-destructive filters in section 9 (rou…
nelsonic Sep 8, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
create basic files for "elmish" Todo List #44
  • Loading branch information
nelsonic committed Jul 5, 2018
commit 6db982a601f50bd600ddefc589afd328ae91a567
89 changes: 89 additions & 0 deletions examples/todo-list/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Define the Component's Actions:
var Inc = 'inc'; // increment the counter
var Dec = 'dec'; // decrement the counter
var Res = 'reset'; // reset counter: git.io/v9KJk

function update(model, action) { // Update function takes the current state
var parts = action ? action.split('-') : []; // e.g: inc-0 where 0 is the counter "id"
var act = parts[0];
var index = parts[1] || 0;
var new_model = JSON.parse(JSON.stringify(model)) // "clone" the model
switch(act) { // and an action (String) runs a switch
case Inc:
new_model.counters[index] = model.counters[index] + 1;
break;
case Dec:
new_model.counters[index] = model.counters[index] - 1;
break;
case Res: // use ES6 Array.fill to create a new array with values set to 0:
new_model.counters[index] = 0;
break;
default: return model; // if action not defined, return curent state.
}
return new_model;
}

function view(signal, model, root) {
empty(root); // clear root element before re-rendering the App (DOM).
model.counters.map(function(counter, index) {
return container(index, [ // wrap DOM nodes in an "container"
button('+', signal, Inc + '-' + index), // append index to action
div('count', counter), // create div w/ count as text
button('-', signal, Dec + '-' + index), // decrement counter
button('Reset', signal, Res + '-' + index) // reset counter
]);
}).forEach(function (el) { root.appendChild(el) }); // forEach is ES5 so IE9+
}

// Mount Function receives all MUV and mounts the app in the "root" DOM Element
function mount(model, update, view, root_element_id) {
var root = document.getElementById(root_element_id); // root DOM element
function signal(action) { // signal function takes action
return function callback() { // and returns callback
model = update(model, action); // update model according to action
view(signal, model, root); // subsequent re-rendering
};
};
view(signal, model, root); // render initial model (once)
}

// 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

// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section
function container(index, elements) {
var con = document.createElement('section');
con.id = index;
con.className = 'counter';
elements.forEach(function(el) { con.appendChild(el) });
return con;
}

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.split('-')[0]; // use action as CSS class
button.id = action;
// console.log(signal, ' action:', action)
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;
div.className = 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;
}
89 changes: 89 additions & 0 deletions examples/todo-list/elmish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Define the Component's Actions:
var Inc = 'inc'; // increment the counter
var Dec = 'dec'; // decrement the counter
var Res = 'reset'; // reset counter: git.io/v9KJk

function update(model, action) { // Update function takes the current state
var parts = action ? action.split('-') : []; // e.g: inc-0 where 0 is the counter "id"
var act = parts[0];
var index = parts[1] || 0;
var new_model = JSON.parse(JSON.stringify(model)) // "clone" the model
switch(act) { // and an action (String) runs a switch
case Inc:
new_model.counters[index] = model.counters[index] + 1;
break;
case Dec:
new_model.counters[index] = model.counters[index] - 1;
break;
case Res: // use ES6 Array.fill to create a new array with values set to 0:
new_model.counters[index] = 0;
break;
default: return model; // if action not defined, return curent state.
}
return new_model;
}

function view(signal, model, root) {
empty(root); // clear root element before re-rendering the App (DOM).
model.counters.map(function(counter, index) {
return container(index, [ // wrap DOM nodes in an "container"
button('+', signal, Inc + '-' + index), // append index to action
div('count', counter), // create div w/ count as text
button('-', signal, Dec + '-' + index), // decrement counter
button('Reset', signal, Res + '-' + index) // reset counter
]);
}).forEach(function (el) { root.appendChild(el) }); // forEach is ES5 so IE9+
}

// Mount Function receives all MUV and mounts the app in the "root" DOM Element
function mount(model, update, view, root_element_id) {
var root = document.getElementById(root_element_id); // root DOM element
function signal(action) { // signal function takes action
return function callback() { // and returns callback
model = update(model, action); // update model according to action
view(signal, model, root); // subsequent re-rendering
};
};
view(signal, model, root); // render initial model (once)
}

// 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

// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section
function container(index, elements) {
var con = document.createElement('section');
con.id = index;
con.className = 'counter';
elements.forEach(function(el) { con.appendChild(el) });
return con;
}

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.split('-')[0]; // use action as CSS class
button.id = action;
// console.log(signal, ' action:', action)
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;
div.className = 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;
}
29 changes: 29 additions & 0 deletions examples/todo-list/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!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="https://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> mount({counters:[0, 1, 2]}, 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="https://code.jquery.com/qunit/qunit-1.18.0.css">
<!-- Load the QUnit Testing Framework from CDN - to run the tests -->
<script src="https://code.jquery.com/qunit/qunit-1.18.0.js"></script>
<!-- Load Blanket.js from CDN - for test coverage stats -->
<script src="https://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>
74 changes: 74 additions & 0 deletions examples/todo-list/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
var id = 'test-app';

test('update({counters:[0]}) returns {counters:[0]} (current state unmodified)',
function(assert) {
var result = update({counters:[0]});
assert.equal(result.counters[0], 0);
});

test('Test Update increment: update(1, "inc") returns 2', function(assert) {
var result = update({counters: [1] }, "inc");
console.log('result', result);
assert.equal(result.counters[0], 2);
});


test('Test Update decrement: update(1, "dec") returns 0', function(assert) {
var result = update({counters: [1] }, "dec");
assert.equal(result.counters[0], 0);
});

test('Test negative state: update(-9, "inc") returns -8', function(assert) {
var result = update({counters: [-9] }, "inc");
assert.equal(result.counters[0], -8);
});

test('mount({model: 7, update: update, view: view}, "'
+ id +'") sets initial state to 7', function(assert) {
mount({counters:[7]}, update, view, id);
var state = document.getElementById(id)
.getElementsByClassName('count')[0].textContent;
assert.equal(state, 7);
});

test('empty("test-app") should clear DOM in root node', function(assert) {
empty(document.getElementById(id));
mount({counters:[7]}, update, view, 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));
mount({counters:[7]}, update, view, id);
document.getElementById(id).getElementsByClassName('inc')[0].click();
var state = document.getElementById(id)
.getElementsByClassName('count')[0].textContent;
assert.equal(state, 8); // model was incremented successfully
empty(document.getElementById(id)); // clean up after tests
});

// Reset Functionality

test('Test reset counter when model/state is 6 returns 0', function(assert) {
var result = update({counters:[7]}, "reset");
assert.equal(result.counters[0], 0);
});

test('reset button should be present on page', function(assert) {
var reset = document.getElementsByClassName('reset');
assert.equal(reset.length, 3);
});

test('Click reset button resets state to 0', function(assert) {
mount({counters:[7]}, update, view, id);
var root = document.getElementById(id);
assert.equal(root.getElementsByClassName('count')[0].textContent, 7);
var btn = root.getElementsByClassName("reset")[0]; // click reset button
btn.click(); // Click the Reset button!
var state = root.getElementsByClassName('count')[0].textContent;
assert.equal(state, 0); // state was successfully reset to 0!
empty(root); // clean up after tests
});
Empty file added todo-list.md
Empty file.