@@ -844,3 +844,197 @@ document.addEventListener('keyup', function handler (e) {
844
844
845
845
when you re-run the tests, they will pass:
846
846
![ cancel-editing-on-esc-keypress-test-passing] ( https://user-images.githubusercontent.com/194400/45189286-15e05d80-b230-11e8-938c-4df80e49fda9.png )
847
+
848
+ ### 6. Counter
849
+
850
+ ```
851
+ ✓ should display the current number of todo items
852
+ ```
853
+
854
+ #### 6. Counter _ Test_
855
+
856
+ Append following test code to your ` test/todo-app.test.js ` file:
857
+
858
+ ``` js
859
+ test .only (' 6. Counter > should display the current number of todo items' ,
860
+ function (t ) {
861
+ elmish .empty (document .getElementById (id));
862
+ const model = {
863
+ todos: [
864
+ { id: 0 , title: " Make something people want." , done: false },
865
+ { id: 1 , title: " Bootstrap for as long as you can" , done: false },
866
+ { id: 2 , title: " Let's solve our own problem" , done: false }
867
+ ],
868
+ hash: ' #/'
869
+ };
870
+ // render the view and append it to the DOM inside the `test-app` node:
871
+ elmish .mount (model, app .update , app .view , id, app .subscriptions );
872
+ // count:
873
+ const count = parseInt (document .getElementById (' count' ).textContent , 10 );
874
+ t .equal (count, model .todos .length , " displays todo item count: " + count);
875
+
876
+ elmish .empty (document .getElementById (id)); // clear DOM ready for next test
877
+ localStorage .removeItem (' todos-elmish_' + id);
878
+ t .end ();
879
+ });
880
+ ```
881
+
882
+ Thankfully, the counter was already implemented above
883
+ so this test ** _ already_ passes** :
884
+
885
+ ![ counter-test-passing] ( https://user-images.githubusercontent.com/194400/45190621-ca7d7d80-b236-11e8-92b3-5a4fbda6f12a.png )
886
+
887
+ Just keep on [ _ movin_ '] ( https://youtu.be/uvRBUw_Ls2o )
888
+
889
+
890
+ ### 7. Clear Completed Button
891
+
892
+ When items are complete we should be able to ` delete ` them in bulk.
893
+
894
+ ```
895
+ ✓ should display the number of completed items
896
+ ✓ should remove completed items when clicked
897
+ ✓ should be hidden when there are no items that are completed
898
+ ```
899
+
900
+ #### 7. Clear Completed Button _ Test_
901
+
902
+ Append following test code to your ` test/todo-app.test.js ` file:
903
+
904
+ ``` js
905
+ test .only (' 7. Clear Completed > should display the number of completed items' ,
906
+ function (t ) {
907
+ elmish .empty (document .getElementById (id));
908
+ const model = {
909
+ todos: [
910
+ { id: 0 , title: " Make something people want." , done: false },
911
+ { id: 1 , title: " Bootstrap for as long as you can" , done: true },
912
+ { id: 2 , title: " Let's solve our own problem" , done: true }
913
+ ],
914
+ hash: ' #/'
915
+ };
916
+ // render the view and append it to the DOM inside the `test-app` node:
917
+ elmish .mount (model, app .update , app .view , id, app .subscriptions );
918
+ // count todo items in DOM:
919
+ t .equal (document .querySelectorAll (' .view' ).length , 3 ,
920
+ " at the start, there are 3 todo items in the DOM." );
921
+
922
+ // count completed items
923
+ const completed_count =
924
+ parseInt (document .getElementById (' completed-count' ).textContent , 10 );
925
+ const done_count = model .todos .filter (function (i ) {return i .done }).length ;
926
+ t .equal (completed_count, done_count,
927
+ " displays completed items count: " + completed_count);
928
+
929
+ // clear completed items:
930
+ const button = document .querySelectorAll (' .clear-completed' )[0 ];
931
+ button .click ();
932
+
933
+ // confirm that there is now only ONE todo list item in the DOM:
934
+ t .equal (document .querySelectorAll (' .view' ).length , 1 ,
935
+ " after clearing completed items, there is only 1 todo item in the DOM." );
936
+
937
+ // no clear completed button in the DOM when there are no "done" todo items:
938
+ t .equal (document .querySelectorAll (' clear-completed' ).length , 0 ,
939
+ ' no clear-completed button when there are no done items.' )
940
+
941
+ elmish .empty (document .getElementById (id)); // clear DOM ready for next test
942
+ localStorage .removeItem (' todos-elmish_' + id);
943
+ t .end ();
944
+ });
945
+ ```
946
+
947
+ #### 7. Clear Completed Button _ Implementation_
948
+
949
+ First we need to update the ` button ` section in the ` render_footer ` function
950
+ to include the ` done ` count:
951
+
952
+ _ Before:_
953
+
954
+ ``` js
955
+ button ([" class=clear-completed" , " style=display:" + display_clear],
956
+ [
957
+ text (" Clear completed" )
958
+ ]
959
+ )
960
+ ```
961
+
962
+ _ After:_
963
+
964
+ ``` js
965
+ button ([" class=clear-completed" , " style=display:" + display_clear,
966
+ signal (' CLEAR_COMPLETED' )
967
+ ],
968
+ [
969
+ text (" Clear completed [" ),
970
+ span ([" id=completed-count" ], [
971
+ text (done)
972
+ ]),
973
+ text (" ]" )
974
+ ]
975
+ )
976
+ ```
977
+
978
+ _ Seconde_ we need to add a ` 'CLEAR_COMPLETED' ` ` case ` to the ` update ` function:
979
+
980
+ ``` js
981
+ case ' CLEAR_COMPLETED' :
982
+ new_model .todos = new_model .todos .filter (function (item ) {
983
+ return ! item .done ; // only return items which are item.done = false
984
+ });
985
+ break ;
986
+ ```
987
+
988
+ The tests should pass:
989
+
990
+ ![ clear-completed-button-tests-passing] ( https://user-images.githubusercontent.com/194400/45191359-a58b0980-b23a-11e8-91bf-dcb016d6f4bb.png )
991
+
992
+ <br />
993
+
994
+ ### 8. Persistence > Save Todo List items to ` localStorage `
995
+
996
+ ```
997
+ ✓ should persist its data
998
+ ```
999
+
1000
+ #### 8. Persistence _ Test_
1001
+
1002
+ We have already covered saving the ` model `
1003
+ to ` localStorage ` in _ detail_ (_ above_ ),
1004
+ we are adding a "proxy" test for completeness:
1005
+
1006
+ ``` js
1007
+ test .only (' 8. Persistence > should persist its data' , function (t ) {
1008
+ elmish .empty (document .getElementById (id));
1009
+ const model = {
1010
+ todos: [
1011
+ { id: 0 , title: " Make something people want." , done: false }
1012
+ ],
1013
+ hash: ' #/'
1014
+ };
1015
+ // render the view and append it to the DOM inside the `test-app` node:
1016
+ elmish .mount (model, app .update , app .view , id, app .subscriptions );
1017
+ // confirm that the model is saved to localStorage
1018
+ console .log (' localStorage' , localStorage .getItem (' todos-elmish_' + id));
1019
+ t .equal (localStorage .getItem (' todos-elmish_' + id),
1020
+ JSON .stringify (model), " data is persisted to localStorage" );
1021
+
1022
+ elmish .empty (document .getElementById (id)); // clear DOM ready for next test
1023
+ localStorage .removeItem (' todos-elmish_' + id);
1024
+ t .end ();
1025
+ });
1026
+ ```
1027
+
1028
+ Again, this test should _ already_ pass:
1029
+
1030
+ ![ persistence-test-passing] ( https://user-images.githubusercontent.com/194400/45190477-0a903080-b236-11e8-991c-bab61efb3d22.png )
1031
+
1032
+ ### 9. Routing
1033
+
1034
+ The following assertions:
1035
+ ```
1036
+ ✓ should allow me to display active items
1037
+ ✓ should allow me to display completed items
1038
+ ✓ should allow me to display all items
1039
+ ✓ should highlight the currently applied filter
1040
+ ```
0 commit comments