From 453b0f8b2f1bcbbe9c68defb29c0c1adb545aa9f Mon Sep 17 00:00:00 2001 From: Brent Jackson Date: Fri, 22 Jun 2018 11:13:15 -0400 Subject: [PATCH] Add tests for components --- .babelrc | 10 + .npmignore | 1 + package.json | 15 +- src/Catch.js | 44 ++-- src/SidebarLayout.js | 1 - src/index.js | 7 +- src/scope.js | 2 +- test/components.js | 260 ++++++++++++++++++++ test/snapshots/build.js.snap | Bin 411 -> 411 bytes test/snapshots/components.js.md | 387 ++++++++++++++++++++++++++++++ test/snapshots/components.js.snap | Bin 0 -> 3192 bytes 11 files changed, 689 insertions(+), 38 deletions(-) create mode 100644 .babelrc create mode 100644 test/components.js create mode 100644 test/snapshots/components.js.md create mode 100644 test/snapshots/components.js.snap diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..8932ea1 --- /dev/null +++ b/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + "env", + "stage-0", + "react" + ], + "plugins": [ + "transform-runtime" + ] +} diff --git a/.npmignore b/.npmignore index c755bc6..447be75 100644 --- a/.npmignore +++ b/.npmignore @@ -8,3 +8,4 @@ examples demo dist .travis.yml +.babelrc diff --git a/package.json b/package.json index aeb1a78..f795c08 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "start": "./cli.js docs -p 8888", "build": "./cli.js build docs", "test": "nyc ava -T 20s", + "test:components": "nyc ava test/components.js", "cover": "nyc report --reporter=html --reporter=lcov" }, "keywords": [ @@ -40,6 +41,7 @@ "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", "babel-register": "^6.26.0", + "browser-env": "^3.2.5", "chalk": "^2.4.1", "clipboardy": "^1.2.3", "connect-history-api-fallback": "^1.5.0", @@ -83,8 +85,10 @@ "ava": "^0.25.0", "isomorphic-fetch": "^2.2.1", "nyc": "^12.0.1", + "react-test-renderer": "^16.4.1", "refunk": "^3.0.1", "rimraf": "^2.6.2", + "sinon": "^6.0.0", "styled-components": "^3.3.2" }, "peerDependencies": { @@ -129,16 +133,7 @@ "require": [ "babel-register" ], - "babel": { - "presets": [ - "env", - "stage-0", - "react" - ], - "plugins": [ - "transform-runtime" - ] - } + "babel": "inherit" }, "engines": { "node": ">=8.0" diff --git a/src/Catch.js b/src/Catch.js index 61091f0..ae57c52 100644 --- a/src/Catch.js +++ b/src/Catch.js @@ -1,11 +1,6 @@ import React from 'react' export default class Catch extends React.Component { - static getDerivedStateFromProps (props, state) { - if (!state.err) return null - return { err: null } - } - state = { err: null } @@ -14,27 +9,30 @@ export default class Catch extends React.Component { this.setState({ err }) } + componentWillReceiveProps (next) { + if (!this.state.err) return + this.setState({ err: null }) + } + render () { const { err } = this.state - if (err) { - return ( -
-      )
-    }
+    if (!err) return this.props.children
 
-    return this.props.children
+    return (
+      
+    )
   }
 }
diff --git a/src/SidebarLayout.js b/src/SidebarLayout.js
index 5bebb06..f851162 100644
--- a/src/SidebarLayout.js
+++ b/src/SidebarLayout.js
@@ -255,7 +255,6 @@ export default class Layout extends React.Component {
       routes = [],
       children,
       route,
-      location,
       title = 'x0',
       logo,
     } = this.props
diff --git a/src/index.js b/src/index.js
index e88f4d4..78ed264 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,9 +1,10 @@
 export { Link, NavLink } from 'react-router-dom'
-export { default as ScopeProvider } from './ScopeProvider'
+export { default as Catch } from './Catch'
+export { default as CenteredLayout } from './CenteredLayout'
+export { default as FileList } from './FileList'
 export { default as LiveEditor } from './LiveEditor'
 export { default as LivePreview } from './LivePreview'
-export { default as FileList } from './FileList'
-export { default as Catch } from './Catch'
+export { default as ScopeProvider } from './ScopeProvider'
 export { default as ScrollTop } from './ScrollTop'
 export { default as scope } from './scope'
 
diff --git a/src/scope.js b/src/scope.js
index 2257fb2..3e3bbfd 100644
--- a/src/scope.js
+++ b/src/scope.js
@@ -11,7 +11,7 @@ const cleanHREF = href => href
   .replace(/\.jsx?$/, '')
 
 export const link = withRouter(({
-  href,
+  href = '',
   match,
   location,
   children,
diff --git a/test/components.js b/test/components.js
new file mode 100644
index 0000000..c7b8e3e
--- /dev/null
+++ b/test/components.js
@@ -0,0 +1,260 @@
+import test from 'ava'
+import React from 'react'
+import { create as render } from 'react-test-renderer'
+import { StaticRouter } from 'react-router-dom'
+import sinon from 'sinon'
+import browserEnv from 'browser-env'
+
+import {
+  Catch,
+  CenteredLayout,
+  FileList,
+  Library,
+  LiveEditor,
+  LivePreview,
+  ScopeProvider,
+  ScrollTop,
+  SidebarLayout,
+  scope
+} from '../src'
+
+browserEnv()
+
+// make sure this doesn't conflict with webpack tests
+global.DIRNAME = __dirname
+
+const renderJSON = el => render(el).toJSON()
+
+test('CenteredLayout renders with active prop', t => {
+  const json = renderJSON(
+    
+      Hello
+    
+  )
+  t.snapshot(json)
+})
+
+test('CenteredLayout does not render without active prop', t => {
+  const json = renderJSON(
+    
+      Hello
+    
+  )
+  t.is(json, 'Hello')
+})
+
+test('Catch renders', t => {
+  const json = renderJSON(
+    Catch
+  )
+  t.snapshot(json)
+})
+
+test('Catch renders error', t => {
+  const Throws = props => {
+    throw new Error('nope')
+    return false
+  }
+  const json = renderJSON(
+    
+      
+    
+  )
+  t.is(json.type, 'pre')
+  t.is(json.children[0], 'Error: nope')
+  t.snapshot(json)
+})
+
+test('FileList renders', t => {
+  const json = renderJSON(
+    
+      
+    
+  )
+  t.snapshot(json)
+})
+
+// doesn't seem to render correctly with refs
+test.skip('LiveEditor renders', t => {
+  const json = renderJSON(
+    
+  )
+  t.snapshot(json)
+})
+
+test('LivePreview renders', t => {
+  const json = renderJSON(
+    
+  )
+  t.snapshot(json)
+})
+
+test('ScopeProvider renders', t => {
+  const json = renderJSON(
+    
+      Hello
+    
+  )
+  t.snapshot(json)
+})
+
+test('ScrollTop renders', t => {
+  const json = renderJSON(
+    
+      
+    
+  )
+  t.is(json, null)
+})
+
+test('ScrollTop scrolls window on location change', t => {
+  sinon.stub(window, 'scrollTo')
+  const instance = render(
+    
+      
+    
+  )
+  instance.update(
+    
+      
+    
+  )
+  t.true(window.scrollTo.calledOnce)
+  window.scrollTo.restore()
+})
+
+test('ScrollTop scrolls to hash', t => {
+  const el = document.body.appendChild(
+    document.createElement('div')
+  )
+  el.id = 'hello'
+  el.scrollIntoView = sinon.spy()
+
+  const instance = render(
+    
+      
+    
+  )
+  instance.update(
+    
+      
+    
+  )
+
+  t.true(el.scrollIntoView.calledOnce)
+})
+
+test('ScrollTop does not scroll to hash when there is no element', t => {
+  const el = document.body.appendChild(
+    document.createElement('div')
+  )
+  el.scrollIntoView = sinon.spy()
+
+  const instance = render(
+    
+      
+    
+  )
+  instance.update(
+    
+      
+    
+  )
+
+  t.false(el.scrollIntoView.calledOnce)
+})
+
+test('Library renders', t => {
+  const json = renderJSON(
+    
+       
Hello
+ }, + ]} + /> +
+ ) + t.snapshot(json) +}) + +test('SidebarLayout renders', t => { + const home = { + key: '/', + path: '/', + name: 'index', + props: {}, + Component: () =>

Home

+ } + const json = renderJSON( + +

About

+ } + ]} + /> +
+ ) + t.snapshot(json) +}) +// console.log(require('util').inspect(json, { depth: null })) + +const blacklist = { + pre: true +} +Object.keys(scope) + .filter(key => !blacklist[key]) + .forEach(key => { + test(`scope.${key} renders`, t => { + const Component = scope[key] + const json = renderJSON( + + + + ) + t.snapshot(json) + }) + }) + +test('scope.pre renders children only', t => { + const json = renderJSON( + React.createElement(scope.pre, null, 'Hello') + ) + t.is(json, 'Hello') +}) + +test('scope.a renders a plain link for absolute URLs', t => { + const Link = scope.a + const json = renderJSON( + + Hello + + ) + t.is(json.props.href, 'http://example.com') + t.snapshot(json) +}) + diff --git a/test/snapshots/build.js.snap b/test/snapshots/build.js.snap index c2796041565a5848348b092c8ff3469f6785510b..527463b8fd0f6cbfbfc6b07053fafe8c3de5f988 100644 GIT binary patch delta 92 zcmV-i0Hgn#1DgXPK~_N^Q*L2!b7*gLAa*ed0RSaQRn-(ZkGfQgtIA)DBvFwfTqU<_ yt)8IBE45kUGLer5VTqOt2 yb9LqEwfyl`e?QxQcq}=Sb7{-%T5D;uneQy#HE!--uCGdwqwokc-4ljD0{{S2*(x0X diff --git a/test/snapshots/components.js.md b/test/snapshots/components.js.md new file mode 100644 index 0000000..72d2d06 --- /dev/null +++ b/test/snapshots/components.js.md @@ -0,0 +1,387 @@ +# Snapshot report for `test/components.js` + +The actual snapshot is saved in `components.js.snap`. + +Generated by [AVA](https://ava.li). + +## Catch renders + +> Snapshot 1 + + 'Catch' + +## CenteredLayout renders with active prop + +> Snapshot 1 + +
+ Hello +
+ +## FileList renders + +> Snapshot 1 + + [ +
+        /Users/bjackson/repos/x0/test
+      
, + , + + +## LivePreview renders + +> Snapshot 1 + +
+
+
+

+ Hello +

+
+
+
Snapshot 1 + + 'Hello + +## Library renders + +> Snapshot 1 + + Snapshot 1 + + [ +
+
+ +

+ x0 +

+
+
+
+
, +
+
+
+

+ x0 +

+
+
+
+ +
+
+
+
+ Content +
+ +
+
, + + +## scope.blockquote renders + +> Snapshot 1 + +
+ +## scope.code renders + +> Snapshot 1 + +
+
+## scope.h1 renders
+
+> Snapshot 1
+
+    

+ +## scope.h2 renders + +> Snapshot 1 + +

+ +## scope.h3 renders + +> Snapshot 1 + +

+ +## scope.h4 renders + +> Snapshot 1 + +

+ +## scope.h5 renders + +> Snapshot 1 + +

+ +## scope.h6 renders + +> Snapshot 1 + +
+ +## scope.hr renders + +> Snapshot 1 + +
+ +## scope.img renders + +> Snapshot 1 + + + +## scope.inlineCode renders + +> Snapshot 1 + + + +## scope.li renders + +> Snapshot 1 + +
  • + +## scope.p renders + +> Snapshot 1 + +

    + +## scope.table renders + +> Snapshot 1 + + + +## scope.ul renders + +> Snapshot 1 + +
      Snapshot 1 + + Snapshot 1 + +
      +      Error: nope
      +    
      Snapshot 1 + +
      + Hello + \ No newline at end of file diff --git a/test/snapshots/components.js.snap b/test/snapshots/components.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..c410deb27da4a2461d4cee1731c23354d4c765ea GIT binary patch literal 3192 zcmV-;42SbURzV00000000xU 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 literal 0 HcmV?d00001