From 7cf511c6b2d11664eb39408954c24a02267c7e23 Mon Sep 17 00:00:00 2001 From: Carlos de Dios Date: Wed, 7 Mar 2018 09:57:19 -0400 Subject: [PATCH 1/2] [Snapshots] - Adding snapshots to testing - Keeping snapshots non-ignored so snapshots always point to the original structure compiled templates should have. --- __test__/.eslintrc | 8 +- __test__/components/TodoItem.test.js | 45 ++++- .../__snapshots__/TodoItem.test.js.snap | 158 ++++++++++++++++++ __test__/services/TodoService.test.js | 12 ++ .../__snapshots__/TodoService.test.js.snap | 31 ++++ __utils__/createControllerFactory.js | 23 ++- __utils__/htmlLoader.js | 8 +- __utils__/styleMock.js | 2 +- __utils__/svgLoader.js | 1 + package-lock.json | 54 ++++++ package.json | 7 +- src/app/components/TodoList/index.js | 5 +- src/app/services/TodoService.js | 8 +- 13 files changed, 347 insertions(+), 15 deletions(-) create mode 100644 __test__/components/__snapshots__/TodoItem.test.js.snap create mode 100644 __test__/services/__snapshots__/TodoService.test.js.snap create mode 100644 __utils__/svgLoader.js diff --git a/__test__/.eslintrc b/__test__/.eslintrc index a17d3f2..177a9b2 100644 --- a/__test__/.eslintrc +++ b/__test__/.eslintrc @@ -1,6 +1,6 @@ { - "globals": [ - "inject", - "angular" - ] + "globals": { + "inject": 1, + "angular": 1 + } } diff --git a/__test__/components/TodoItem.test.js b/__test__/components/TodoItem.test.js index 2e5e4af..0f6a7b3 100644 --- a/__test__/components/TodoItem.test.js +++ b/__test__/components/TodoItem.test.js @@ -3,6 +3,7 @@ import createControllerFactory from '../../__utils__/createControllerFactory'; describe('TodoItem', function() { + let createElement; let createController; beforeEach(() => { @@ -11,9 +12,10 @@ describe('TodoItem', function() { }); - beforeEach(inject(createControllerFactory('todoItem', creator => { + beforeEach(inject(createControllerFactory('todoItem', (controllerCreator, elementCreator) => { - createController = creator; + createElement = elementCreator; + createController = controllerCreator; }))); @@ -58,4 +60,43 @@ describe('TodoItem', function() { }); + describe("Snapshot Testing", function() { + + it('should render the element when no todo is provided', function() { + + const element = createElement('todoItem'); + + expect(element).toBeDefined(); + expect(element[0]).toMatchSnapshot(); + + }); + + it('should render the element when todo is provided with id', function() { + + const element = createElement('todoItem', { + todo: { + id: 5 + } + }); + + expect(element).toBeDefined(); + expect(element[0]).toMatchSnapshot(); + + }); + + it('should render the element when todo is provided with a title', function() { + + const element = createElement('todoItem', { + todo: { + title: "Hello!" + } + }); + + expect(element).toBeDefined(); + expect(element[0]).toMatchSnapshot(); + + }); + + }); + }); diff --git a/__test__/components/__snapshots__/TodoItem.test.js.snap b/__test__/components/__snapshots__/TodoItem.test.js.snap new file mode 100644 index 0000000..40373a4 --- /dev/null +++ b/__test__/components/__snapshots__/TodoItem.test.js.snap @@ -0,0 +1,158 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TodoItem Snapshot Testing should render the element when no todo is provided 1`] = ` + + + +
+ + + + + + +
+ + +
+`; + +exports[`TodoItem Snapshot Testing should render the element when todo is provided with a title 1`] = ` + + + +
+ + + + + + + + + + + + + svg-icon + + + + +
+ + +
+`; + +exports[`TodoItem Snapshot Testing should render the element when todo is provided with id 1`] = ` + + + +
+ + + + + + +
+ + +
+`; diff --git a/__test__/services/TodoService.test.js b/__test__/services/TodoService.test.js index e8c0d28..ed1e3dc 100644 --- a/__test__/services/TodoService.test.js +++ b/__test__/services/TodoService.test.js @@ -31,6 +31,8 @@ describe("TodoService", function() { expect(todo.completed).toEqual(false); expect(todo.title).toEqual(data.title); + expect(todo).toMatchSnapshot(); + }); it('should store a new todo on the "datasource" collection', async function() { @@ -43,6 +45,8 @@ describe("TodoService", function() { expect(todos.length).toEqual(1); expect(R.last(todos)).toEqual(todo); + expect(todo).toMatchSnapshot(); + }); it('should allow you to update an existing todo', async function() { @@ -57,6 +61,8 @@ describe("TodoService", function() { expect(updatedTodo.title).toEqual('Hello 2'); expect(updatedTodo.completed).toEqual(todo.completed); + expect(updatedTodo).toMatchSnapshot(); + }); it('should allow you to delete existing todos', async function() { @@ -72,6 +78,8 @@ describe("TodoService", function() { expect(deleted).toEqual(true); expect(allTodos.length).toEqual(0); + expect(allTodos).toMatchSnapshot(); + }); it('should throw an error if todo id does not exist when trying to update', async function() { @@ -84,6 +92,8 @@ describe("TodoService", function() { expect(e.message).toEqual('Todo not found'); + expect(e).toMatchSnapshot(); + } }); @@ -98,6 +108,8 @@ describe("TodoService", function() { expect(e.message).toEqual('Todo not found'); + expect(e).toMatchSnapshot(); + } }); diff --git a/__test__/services/__snapshots__/TodoService.test.js.snap b/__test__/services/__snapshots__/TodoService.test.js.snap new file mode 100644 index 0000000..2380b5e --- /dev/null +++ b/__test__/services/__snapshots__/TodoService.test.js.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TodoService should allow you to delete existing todos 1`] = `Array []`; + +exports[`TodoService should allow you to update an existing todo 1`] = ` +Object { + "completed": false, + "id": 8, + "title": "Hello 2", +} +`; + +exports[`TodoService should return a new instance of a Todo object on \`new\` call 1`] = ` +Todo { + "completed": false, + "id": 6, + "title": "Hello", +} +`; + +exports[`TodoService should store a new todo on the "datasource" collection 1`] = ` +Todo { + "completed": false, + "id": 7, + "title": "Hello", +} +`; + +exports[`TodoService should throw an error if todo id does not exist when trying to delete 1`] = `[Error: Todo not found]`; + +exports[`TodoService should throw an error if todo id does not exist when trying to update 1`] = `[Error: Todo not found]`; diff --git a/__utils__/createControllerFactory.js b/__utils__/createControllerFactory.js index 8f11065..70eb5db 100644 --- a/__utils__/createControllerFactory.js +++ b/__utils__/createControllerFactory.js @@ -1,6 +1,6 @@ export default function(controllerName, cb) { - return function($componentController) { + return function($componentController, $rootScope, $compile) { cb(function(params) { @@ -10,6 +10,27 @@ export default function(controllerName, cb) { return controller; + }, function(elementName, props = {}) { + const scope = $rootScope.$new(); + const keys = Object.keys(props); + Object.assign(scope, props); + + const htmlElementName = camelCaseToDashCase(elementName); + + const htmlProps = keys.map(key => { + return `${camelCaseToDashCase(key)}="${key}"` + }, '').join(' '); + + const element = $compile(`<${htmlElementName} ${htmlProps}>`)(scope); + + scope.$apply(); // Make sure we actually perform any HTML change + + return element; + + function camelCaseToDashCase(str) { + return str.replace(/[A-Z]/g, $1 => `-${$1.toLowerCase()}`); + } + }); }; diff --git a/__utils__/htmlLoader.js b/__utils__/htmlLoader.js index 524219e..b56b7a5 100644 --- a/__utils__/htmlLoader.js +++ b/__utils__/htmlLoader.js @@ -1 +1,7 @@ -module.exports = "" +const htmlLoader = require('html-loader'); + +module.exports = { + process(src) { + return htmlLoader(src); + } +}; diff --git a/__utils__/styleMock.js b/__utils__/styleMock.js index f053ebf..80d0d98 100644 --- a/__utils__/styleMock.js +++ b/__utils__/styleMock.js @@ -1 +1 @@ -module.exports = {}; +module.exports = "styling-file"; diff --git a/__utils__/svgLoader.js b/__utils__/svgLoader.js new file mode 100644 index 0000000..dc29280 --- /dev/null +++ b/__utils__/svgLoader.js @@ -0,0 +1 @@ +module.exports = "svg-icon"; diff --git a/package-lock.json b/package-lock.json index c8fb49b..59acc3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6012,6 +6012,60 @@ "detect-newline": "2.1.0" } }, + "jest-dot-reporter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/jest-dot-reporter/-/jest-dot-reporter-1.0.3.tgz", + "integrity": "sha512-c4fz3dRh7qfoaF2Lwp1yWUvKK65hp4g9aVA6mDCsUTS7wZfYkI4NRxHsXA0P4dOWCtdTfZoXBPW/WP8nAA0eYA==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "moment": "2.18.1", + "progress": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "moment": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", + "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "jest-environment-jsdom": { "version": "22.4.1", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.1.tgz", diff --git a/package.json b/package.json index 7a16592..f325edf 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "html-loader": "^0.5.5", "html-webpack-plugin": "^2.30.1", "jest": "^22.3.0", + "jest-dot-reporter": "^1.0.3", "jquery": "^3.3.1", "moment": "^2.20.1", "ng-annotate": "^1.2.2", @@ -68,10 +69,14 @@ "src", "node_modules" ], + "reporters": [ + "jest-dot-reporter" + ], "moduleNameMapper": { "^models$": "/src/app/models", + "\\.(svg)$": "/__utils__/svgLoader.js", "\\.(html)$": "/__utils__/htmlLoader.js", - "\\.(css|styl|svg)$": "/__utils__/styleMock.js" + "\\.(css|styl)$": "/__utils__/styleMock.js" }, "collectCoverageFrom": [ "src/**/*.js", diff --git a/src/app/components/TodoList/index.js b/src/app/components/TodoList/index.js index 4a51b31..f085b96 100644 --- a/src/app/components/TodoList/index.js +++ b/src/app/components/TodoList/index.js @@ -47,10 +47,7 @@ class TodoListController { return true; - }).catch(error => { - // eslint-disable-next-line no-console - console.log(error); - + }).catch(() => { return false; }); diff --git a/src/app/services/TodoService.js b/src/app/services/TodoService.js index c703a06..e97d3d7 100644 --- a/src/app/services/TodoService.js +++ b/src/app/services/TodoService.js @@ -2,7 +2,13 @@ import * as R from 'ramda'; import { Todo } from 'models'; import Promise from 'bluebird'; -const todos = []; +const todos = [ + Todo.new("Learn Jest", true), + Todo.new("Learn React", true), + Todo.new("Learn AngularJS", true), + Todo.new("Take over the world!", false), + Todo.new("Figure out how much wood I'd chuck as a woodchuck", false), +]; export default class TodoService { all = () => { From e1a6073cb95ad318b32618923ef657de69b3761b Mon Sep 17 00:00:00 2001 From: Carlos de Dios Date: Wed, 7 Mar 2018 10:08:48 -0400 Subject: [PATCH 2/2] Removing `develop` from .travis.yml - We don't need to run travis ci for each push to `develop` on this scenario, we only need PR checking when attempting to merge a PR to master. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 76cbd51..850b22f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,6 @@ script: branches: only: - master - - develop after_script: - cat ./coverage/lcov.info | yarn coveralls