From e90d5becea2204dcd6b3ede8be45d6412a7360ec Mon Sep 17 00:00:00 2001
From: vogloblinsky <vincent.ogloblinsky@gmail.com>
Date: Tue, 15 Nov 2016 17:43:19 +0100
Subject: [PATCH 1/2] feat(app): first tests

---
 src/app/list/list.component.ts        | 12 ++---
 src/app/shared/services/todo.store.ts | 70 +++++++++++++++++++--------
 2 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/src/app/list/list.component.ts b/src/app/list/list.component.ts
index ea81b0d..bf90ddf 100644
--- a/src/app/list/list.component.ts
+++ b/src/app/list/list.component.ts
@@ -26,24 +26,20 @@ export class ListComponent {
     constructor(todoStore: TodoStore) {
         let that = this;
 		this.todoStore = todoStore;
-        this.todos = todoStore.getAll();
-        this.watchTest = Observable.of(todoStore.todos);
+        //this.todos = todoStore.getAll();
         EmitterService.get('FooterComponent').subscribe((value) => {
             console.log(value);
             switch (value) {
                 case 'displayCompleted':
-                    that.todos = todoStore.getCompleted();
+                    //that.todos = todoStore.getCompleted();
                     break;
                 case 'displayAll':
-                    that.todos = todoStore.getAll();
+                    //that.todos = todoStore.getAll();
                     break;
                 case 'displayRemaining':
-                    that.todos = todoStore.getRemaining();
+                    //that.todos = todoStore.getRemaining();
                     break;
             }
         });
-        this.watchTest.subscribe(data => {
-            console.log(data);
-        });
 	}
 }
diff --git a/src/app/shared/services/todo.store.ts b/src/app/shared/services/todo.store.ts
index 1877581..450e31c 100644
--- a/src/app/shared/services/todo.store.ts
+++ b/src/app/shared/services/todo.store.ts
@@ -1,4 +1,6 @@
 import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { Subject } from 'rxjs/Subject';
 
 import { Todo } from '../models/todo.model';
 
@@ -10,98 +12,124 @@ export class TodoStore {
     /**
      *  Local array of Todos
      */
-    todos: Array<Todo>;
+    todos: any;
 
     constructor() {
         let persistedTodos = JSON.parse(localStorage.getItem('angular2-todos') || '[]');
-        // Normalize back into classes
+        console.log(persistedTodos);
+
+        this.todos = new Subject();
+
+        this.todos.subscribe(
+            function (x) {
+                console.log('Next: ', x);
+            },
+            function (err) {
+                console.log('Error: ' + err);
+            },
+            function () {
+                console.log('Completed');
+            }
+        );
+
+        this.todos.next(new Todo('test'));
+
+        /*this.todos = new Observable<Todo[]>(observer => {
+            observer.next(new Todo('test'));
+        });
+        let subscription = this.todos.subscribe(value => {
+              console.log(value);
+        });
+        this.todos.next(persistedTodos);*/
+        /*// Normalize back into classes
         this.todos = persistedTodos.map((todo: { _title: String, completed: Boolean }) => {
             let ret = new Todo(todo._title);
             ret.completed = todo.completed;
             return ret;
-        });
+        });*/
     }
 
     private updateStore() {
-        localStorage.setItem('angular2-todos', JSON.stringify(this.todos));
+        //localStorage.setItem('angular2-todos', JSON.stringify(this.todos));
     }
 
     private getWithCompleted(completed: Boolean) {
-        return this.todos.filter((todo: Todo) => todo.completed === completed);
+        //return this.todos.filter((todo: Todo) => todo.completed === completed);
     }
 
     /**
      *  All the todos are they __completed__ ?
      */
-    allCompleted(): boolean {
-        return this.todos.length === this.getCompleted().length;
+    allCompleted(): any {
+        //return this.todos.length === this.getCompleted().length;
     }
 
     /**
      *  Set all todos status (completed or not)
      */
     setAllTo(completed: Boolean) {
-        this.todos.forEach((t: Todo) => t.completed = completed);
-        this.updateStore();
+        //this.todos.forEach((t: Todo) => t.completed = completed);
+        //this.updateStore();
     }
 
     /**
      *  Remove completed todos
      */
     removeCompleted() {
-        this.todos = this.getWithCompleted(false);
-        this.updateStore();
+        //this.todos = this.getWithCompleted(false);
+        //this.updateStore();
     }
 
     /**
      *  Get remaining todos
      */
     getRemaining() {
-        return this.getWithCompleted(false);
+        //return this.getWithCompleted(false);
     }
 
     /**
      *  Get all todos
      */
     getAll() {
-        return this.todos;
+        //return this.todos.asObservable();
     }
 
     /**
      *  Get completed todos
      */
     getCompleted() {
-        return this.getWithCompleted(true);
+        //return this.getWithCompleted(true);
     }
 
     /**
      *  Toggle completed todo status
      */
     toggleCompletion(todo: Todo) {
-        todo.completed = !todo.completed;
-        this.updateStore();
+        //todo.completed = !todo.completed;
+        //this.updateStore();
     }
 
     /**
      *  Remove todo
      */
     remove(todo: Todo) {
-        this.todos.splice(this.todos.indexOf(todo), 1);
-        this.updateStore();
+        //this.todos.splice(this.todos.indexOf(todo), 1);
+        //this.updateStore();
     }
 
     /**
      *  Update store
      */
     update() {
-        this.updateStore();
+        //this.updateStore();
     }
 
     /**
      *  Add todo
      */
     add(title: String) {
-        this.todos.push(new Todo(title));
-        this.updateStore();
+        //this.todos.next(this.todos.getValue().push(new Todo(title)));
+        //this.todos.push(new Todo(title));
+        //this.updateStore();
     }
 }

From c22cb2c66d8fbd655bc1c0b68868233b06bdbe19 Mon Sep 17 00:00:00 2001
From: vogloblinsky <vincent.ogloblinsky@gmail.com>
Date: Wed, 16 Nov 2016 17:46:02 +0100
Subject: [PATCH 2/2] feat(app): first reactive tests

---
 src/app/list/list.component.html      |  2 +-
 src/app/list/list.component.ts        | 10 +++-
 src/app/shared/services/todo.store.ts | 46 ++++++++----------
 src/rxjs-test.html                    | 69 +++++++++++++++++++++++++++
 4 files changed, 99 insertions(+), 28 deletions(-)
 create mode 100644 src/rxjs-test.html

diff --git a/src/app/list/list.component.html b/src/app/list/list.component.html
index c03a2c9..68ba2db 100644
--- a/src/app/list/list.component.html
+++ b/src/app/list/list.component.html
@@ -2,7 +2,7 @@
         *ngIf="todoStore.todos.length" #toggleall
         [checked]="todoStore.allCompleted()"
         (click)="todoStore.setAllTo(toggleall.checked)">
-<div *ngIf="todoStore.todos.length > 0">
+<div *ngIf="todos.length > 0">
     <ul class="todo-list" >
         <todo *ngFor="let todo of todos" [todo]='todo'></todo>
     </ul>
diff --git a/src/app/list/list.component.ts b/src/app/list/list.component.ts
index bf90ddf..c4c4562 100644
--- a/src/app/list/list.component.ts
+++ b/src/app/list/list.component.ts
@@ -20,12 +20,18 @@ export class ListComponent {
      * Local reference of TodoStore
      */
     todoStore: TodoStore;
-    todos: Array<Todo>;
-    watchTest;
+    todos: any = [];
 
     constructor(todoStore: TodoStore) {
         let that = this;
 		this.todoStore = todoStore;
+
+        this.todoStore.todos
+            .subscribe((data) => {
+                console.log(data);
+                this.todos = data;
+            });
+
         //this.todos = todoStore.getAll();
         EmitterService.get('FooterComponent').subscribe((value) => {
             console.log(value);
diff --git a/src/app/shared/services/todo.store.ts b/src/app/shared/services/todo.store.ts
index 450e31c..5fdf306 100644
--- a/src/app/shared/services/todo.store.ts
+++ b/src/app/shared/services/todo.store.ts
@@ -1,6 +1,6 @@
 import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs/Observable';
-import { Subject } from 'rxjs/Subject';
+import { Subject, ReplaySubject } from 'rxjs';
 
 import { Todo } from '../models/todo.model';
 
@@ -12,35 +12,30 @@ export class TodoStore {
     /**
      *  Local array of Todos
      */
-    todos: any;
+    initialTodos: any[] = [];
+
+    todos = new ReplaySubject(1);
+    updates = new Subject();
+    addTodo = new Subject();
 
     constructor() {
         let persistedTodos = JSON.parse(localStorage.getItem('angular2-todos') || '[]');
         console.log(persistedTodos);
 
-        this.todos = new Subject();
-
-        this.todos.subscribe(
-            function (x) {
-                console.log('Next: ', x);
-            },
-            function (err) {
-                console.log('Error: ' + err);
-            },
-            function () {
-                console.log('Completed');
-            }
-        );
-
-        this.todos.next(new Todo('test'));
-
-        /*this.todos = new Observable<Todo[]>(observer => {
-            observer.next(new Todo('test'));
-        });
-        let subscription = this.todos.subscribe(value => {
-              console.log(value);
-        });
-        this.todos.next(persistedTodos);*/
+        this.updates
+            .scan((accumulator: Object[], operation: Function) => {
+                return operation(accumulator);
+            }, this.initialTodos)
+            .subscribe(this.todos);
+
+        this.addTodo
+            .map((todo) => {
+                return (state) => {
+                    return state.concat(todo);
+                }
+            })
+            .subscribe(this.updates);
+
         /*// Normalize back into classes
         this.todos = persistedTodos.map((todo: { _title: String, completed: Boolean }) => {
             let ret = new Todo(todo._title);
@@ -131,5 +126,6 @@ export class TodoStore {
         //this.todos.next(this.todos.getValue().push(new Todo(title)));
         //this.todos.push(new Todo(title));
         //this.updateStore();
+        this.addTodo.next(new Todo(title));
     }
 }
diff --git a/src/rxjs-test.html b/src/rxjs-test.html
new file mode 100644
index 0000000..d2c4353
--- /dev/null
+++ b/src/rxjs-test.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<html class="no-js" lang="">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+</head>
+
+<body>
+
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.0-rc.3/Rx.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
+    <script>
+        var data = [1, 2, 3],
+
+            updates = new Rx.Subject(),
+            numbers = new Rx.ReplaySubject(1),
+            addNumber = new Rx.Subject(),
+            removeNumber = new Rx.Subject();
+
+        updates
+            .scan((accumulator, operation) => {
+                return operation(accumulator);
+            }, data)
+            .subscribe(numbers);
+
+        addNumber
+            .map((number) => {
+                return (state) => {
+                    return state.concat(number);
+                }
+            })
+            .subscribe(updates);
+
+        removeNumber
+            .map((number) => {
+                return (state) => {
+                    return state.filter((numbers) => {
+                        return numbers !== number;
+                    })
+                }
+            })
+            .subscribe(updates);
+
+        numbers.subscribe((value) => {
+            console.log(value)
+        });
+
+        var add = function(number) {
+                addNumber.next(number);
+            },
+
+            remove = function(number) {
+                removeNumber.next(number);
+            };
+
+        setTimeout(function() {
+            add(4);
+            setTimeout(function() {
+                remove(1);
+            }, 1000);
+        }, 500);
+    </script>
+</body>
+
+</html>
