Repository: vigetlabs/microcosm
Pull request #333 (2017-05-24 11:49:00)

Implement toJSON for Action and History
This allows serialization of history for developer tools. This lets you do:

```javascript
JSON.stringify(repo.history) 
// { size: 3, root: { id: 0, status: 'resolved', payload: true, children: [...] }
```

This is for:

https://github.com/vigetlabs/microcosm-devtools

codecov-io: # [Codecov](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=h1) Report
> Merging [#333](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=desc) into [master](https://codecov.io/gh/vigetlabs/microcosm/commit/dfe1d0d60ddd3f8fb046c62e70f0208ca8a5992d?src=pr&el=desc) will **decrease** coverage by `0.24%`.
> The diff coverage is `0%`.

[![Impacted file tree graph](https://codecov.io/gh/vigetlabs/microcosm/pull/333/graphs/tree.svg?token=AaE0FLz9sU&width=650&height=150&src=pr)](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #333      +/-   ##
==========================================
- Coverage     100%   99.75%   -0.25%     
==========================================
  Files          24       24              
  Lines         820      822       +2     
==========================================
  Hits          820      820              
- Misses          0        2       +2
```


| [Impacted Files](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/action.js](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=tree#diff-c3JjL2FjdGlvbi5qcw==) | `98.8% <0%> (-1.2%)` | :arrow_down: |
| [src/history.js](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=tree#diff-c3JjL2hpc3RvcnkuanM=) | `99% <0%> (-1%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=footer). Last update [dfe1d0d...aa94605](https://codecov.io/gh/vigetlabs/microcosm/pull/333?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

nhunzaker: @efatsi Made a few updates and added some test coverage. I feel like this is probably going to need to change to fit the needs of the dev tools, but it at least illustrates the technique.

Patch:
diff --git a/src/action.js b/src/action.js
index 8ffcfe1b..b3e0c0ef 100644
--- a/src/action.js
+++ b/src/action.js
@@ -290,6 +290,16 @@ class Action extends Emitter {
       }
     }
   }
+
+  toJSON() {
+    return {
+      id: this.id,
+      status: this.status,
+      type: this.type,
+      payload: this.payload,
+      children: this.children
+    }
+  }
 }
 
 /**
diff --git a/src/history.js b/src/history.js
index 4aa650b3..6082451b 100644
--- a/src/history.js
+++ b/src/history.js
@@ -345,6 +345,18 @@ class History extends Emitter {
       cursor = cursor.parent
     }
   }
+
+  /**
+   * Serialize history into JSON data
+   */
+  toJSON() {
+    return {
+      head: this.head.id,
+      root: this.root.id,
+      size: this.size,
+      tree: this.root
+    }
+  }
 }
 
 export default History


Test patch:
diff --git a/test/unit/history/__snapshots__/toJSON.test.js.snap b/test/unit/history/__snapshots__/toJSON.test.js.snap
new file mode 100644
index 00000000..2cb61884
--- /dev/null
+++ b/test/unit/history/__snapshots__/toJSON.test.js.snap
@@ -0,0 +1,24 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`History::toJSON serializes the tree of actions 1`] = `
+Object {
+  "head": 12,
+  "root": 10,
+  "size": 2,
+  "tree": Object {
+    "children": Array [
+      Object {
+        "children": Array [],
+        "id": 12,
+        "payload": true,
+        "status": "resolve",
+        "type": "action.5",
+      },
+    ],
+    "id": 10,
+    "payload": undefined,
+    "status": "resolve",
+    "type": "$start.3",
+  },
+}
+`;
diff --git a/test/unit/history/toJSON.test.js b/test/unit/history/toJSON.test.js
new file mode 100644
index 00000000..8366adb5
--- /dev/null
+++ b/test/unit/history/toJSON.test.js
@@ -0,0 +1,44 @@
+import History from '../../../src/history'
+
+describe('History::toJSON', function() {
+  const action = n => n
+
+  it('includes the size of the tree', function() {
+    const history = new History({ maxHistory: Infinity })
+
+    history.append(action).resolve()
+    history.append(action).resolve()
+
+    let json = JSON.parse(JSON.stringify(history))
+
+    expect(json.size).toEqual(3)
+  })
+
+  it('includes an id reference to the head', function() {
+    const history = new History({ maxHistory: Infinity })
+
+    history.append(action).resolve()
+
+    let json = JSON.parse(JSON.stringify(history))
+
+    expect(json.head).toEqual(history.head.id)
+  })
+
+  it('includes an id reference to the root', function() {
+    const history = new History({ maxHistory: Infinity })
+
+    history.append(action).resolve()
+
+    let json = JSON.parse(JSON.stringify(history))
+
+    expect(json.root).toEqual(history.root.id)
+  })
+
+  it('serializes the tree of actions', function() {
+    const history = new History({ maxHistory: Infinity })
+
+    history.append(action).resolve(true)
+
+    expect(history).toMatchSnapshot()
+  })
+})