Repository: vigetlabs/microcosm
Pull request #340 (2017-06-02 11:53:00)

Prevent case where Microcosm register method caused infinite loop
If a microcosm was added to a domain engine, the deserialize method was getting picked up. This commit changes the way microcosm registration happens to avoid an infinite loop.


codecov-io: # [Codecov](https://codecov.io/gh/vigetlabs/microcosm/pull/340?src=pr&el=h1) Report
> Merging [#340](https://codecov.io/gh/vigetlabs/microcosm/pull/340?src=pr&el=desc) into [master](https://codecov.io/gh/vigetlabs/microcosm/commit/210e760b4e568dd371f2b6d42943cfca341a4cd0?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

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

```diff
@@          Coverage Diff          @@
##           master   #340   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files          24     24           
  Lines         855    857    +2     
=====================================
+ Hits          855    857    +2
```


| [Impacted Files](https://codecov.io/gh/vigetlabs/microcosm/pull/340?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/domain-engine.js](https://codecov.io/gh/vigetlabs/microcosm/pull/340?src=pr&el=tree#diff-c3JjL2RvbWFpbi1lbmdpbmUuanM=) | `100% <100%> (ø)` | :arrow_up: |
| [src/microcosm.js](https://codecov.io/gh/vigetlabs/microcosm/pull/340?src=pr&el=tree#diff-c3JjL21pY3JvY29zbS5qcw==) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/vigetlabs/microcosm/pull/340?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/340?src=pr&el=footer). Last update [210e760...9f4055d](https://codecov.io/gh/vigetlabs/microcosm/pull/340?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

mackermedia: 👍 

Patch:
diff --git a/src/domain-engine.js b/src/domain-engine.js
index 7dd4d0c1..489ef157 100644
--- a/src/domain-engine.js
+++ b/src/domain-engine.js
@@ -14,19 +14,24 @@ class DomainEngine {
 
     // All realms contain a meta domain for basic Microcosm operations
     this.add([], MetaDomain)
-
-    // Microcosms can register actions
-    this.addRepo(repo)
   }
 
-  addRepo(repo) {
-    if (typeof repo.register !== 'undefined') {
-      this.domains.push([[], repo])
+  getRepoHandlers(action) {
+    let { command, status } = action
+
+    let handler = null
+
+    if (this.repo.register) {
+      handler = getRegistration(this.repo.register(), command, status)
     }
+
+    return handler ? [{ key: [], domain: this.repo, handler }] : []
   }
 
-  getHandlers({ command, status }) {
-    let handlers = []
+  getHandlers(action) {
+    let handlers = this.getRepoHandlers(action)
+
+    let { command, status } = action
 
     for (var i = 0, len = this.domains.length; i < len; i++) {
       var [key, domain] = this.domains[i]


Test patch:
diff --git a/test/unit/microcosm/register.test.js b/test/unit/microcosm/register.test.js
index d8ed2a68..4c42d995 100644
--- a/test/unit/microcosm/register.test.js
+++ b/test/unit/microcosm/register.test.js
@@ -1,7 +1,7 @@
 import Microcosm, { update } from '../../../src/microcosm'
 
 describe('Microcosm::register', function() {
-  it('a Microcosm can register to actiosn', function() {
+  it('a Microcosm can register to actions', function() {
     const ADD = 'ADD'
 
     class Repo extends Microcosm {
@@ -27,4 +27,51 @@ describe('Microcosm::register', function() {
 
     expect(repo).toHaveState('count', 4)
   })
+
+  describe('lifecycle hooks', function() {
+    it('does not call deserialize infinitely', function() {
+      class Repo extends Microcosm {
+        register() {
+          return {}
+        }
+      }
+
+      let repo = new Repo()
+      let spy = jest.spyOn(repo, 'deserialize')
+
+      repo.deserialize()
+
+      expect(spy).toHaveBeenCalledTimes(1)
+    })
+
+    it('does not call serialize infinitely', function() {
+      class Repo extends Microcosm {
+        register() {
+          return {}
+        }
+      }
+
+      let repo = new Repo()
+      let spy = jest.spyOn(repo, 'serialize')
+
+      repo.serialize()
+
+      expect(spy).toHaveBeenCalledTimes(1)
+    })
+
+    it('does not call getInitialState infinitely', function() {
+      class Repo extends Microcosm {
+        register() {
+          return {}
+        }
+      }
+
+      let repo = new Repo()
+      let spy = jest.spyOn(repo, 'getInitialState')
+
+      repo.getInitialState()
+
+      expect(spy).toHaveBeenCalledTimes(1)
+    })
+  })
 })