Repository: mzgoddard/preact-render-spy
Pull request #35 (2017-07-17 19:56:50)

Add test/case for null outputs


Patch:
diff --git a/src/preact-render-spy.js b/src/preact-render-spy.js
index b91377c..748ba3f 100644
--- a/src/preact-render-spy.js
+++ b/src/preact-render-spy.js
@@ -128,7 +128,7 @@ const vdomIter = function* (vdomMap, vdom) {
     return;
   }
   yield vdom;
-  if (typeof vdom.nodeName === 'function') {
+  if (typeof vdom.nodeName === 'function' && vdomMap.has(vdom)) {
     yield* vdomIter(vdomMap, vdomMap.get(vdom));
   }
   else {
@@ -258,7 +258,7 @@ class FindWrapper {
       throw new Error('preact-render-spy: Must have only 1 result for .output().');
     }
 
-    if (typeof this[0].nodeName !== 'function') {
+    if (!this[0] || typeof this[0].nodeName !== 'function') {
       throw new Error('preact-render-spy: Must have a result of a preact class or function component for .output()');
     }
 
@@ -271,6 +271,10 @@ class FindWrapper {
       while (this.context.vdomMap.has(nodeOutput)) {
         nodeOutput = this.context.vdomMap.get(nodeOutput);
       }
+      // in case the node output null or false...
+      if (!nodeOutput) {
+        return nodeOutput;
+      }
       const clone = h(
         nodeOutput.nodeName,
         nodeOutput.attributes,
@@ -288,10 +292,15 @@ class FindWrapper {
       if (typeof jsx.nodeName === 'function') {
         jsx = this.at(index).output();
       }
+      if (!jsx) return `{${JSON.stringify(jsx)}}`;
       return renderToString(jsx, {}, config.toStringOptions, true);
     };
 
-    return `preact-render-spy (${this.length} nodes)
+    const header = `preact-render-spy (${this.length} nodes)`;
+    if (!this.length) {
+      return header;
+    }
+    return `${header}
 -------
 ${Array.from(this).map(render).join('\n')}
 `;


Test patch:
diff --git a/src/__snapshots__/shared-render.test.js.snap b/src/__snapshots__/shared-render.test.js.snap
index 24935a0..1d11de8 100644
--- a/src/__snapshots__/shared-render.test.js.snap
+++ b/src/__snapshots__/shared-render.test.js.snap
@@ -23,6 +23,15 @@ preact-render-spy (3 nodes)
 
 exports[`deep: output matches snapshot 1`] = `<div>second first</div>`;
 
+exports[`deep: weird render cases toString matches snapshot 1`] = `
+"preact-render-spy (1 nodes)
+-------
+{null}
+"
+`;
+
+exports[`deep: weird render cases toString matches snapshot 2`] = `preact-render-spy (0 nodes)`;
+
 exports[`shallow: context matches snapshot 1`] = `
 preact-render-spy (1 nodes)
 -------
@@ -45,3 +54,19 @@ preact-render-spy (3 nodes)
 `;
 
 exports[`shallow: output matches snapshot 1`] = `<Second>first</Second>`;
+
+exports[`shallow: weird render cases toString matches snapshot 1`] = `
+"preact-render-spy (1 nodes)
+-------
+<NullStateless>
+  <Div></Div>
+</NullStateless>
+"
+`;
+
+exports[`shallow: weird render cases toString matches snapshot 2`] = `
+preact-render-spy (1 nodes)
+-------
+<Div></Div>
+
+`;
diff --git a/src/shared-render.test.js b/src/shared-render.test.js
index 8de480b..15a6122 100644
--- a/src/shared-render.test.js
+++ b/src/shared-render.test.js
@@ -157,6 +157,11 @@ const sharedTests = (name, func) => {
     expect(context.output()).toEqual(<div><span /></div>);
   });
 
+  it(`${name}: output returns null output by a Component`, () => {
+    const context = func(<NullStateless/>);
+    expect(context.output()).toEqual(null);
+  });
+
   it(`${name}: simulate an event`, () => {
     let count = 0;
     let context = func(<div onClick={() => {count++;}}/>);
@@ -202,6 +207,13 @@ const sharedTests = (name, func) => {
     </div>);
     expect(context.find('span')).toMatchSnapshot();
   });
+
+  it(`${name}: weird render cases toString matches snapshot`, () => {
+    const Test = () => <NullStateless><Div /></NullStateless>;
+    const context = func(<Test />);
+    expect(context.toString()).toMatchSnapshot();
+    expect(context.find('Div')).toMatchSnapshot();
+  });
 };
 
 sharedTests('deep', deep);