From aa2ce1ab009f2c50600ce92793046bd73005031a Mon Sep 17 00:00:00 2001 From: Sharikov Vladislav Date: Tue, 28 Nov 2017 23:18:31 +0300 Subject: [PATCH 01/10] feat: remove ng* attributes from component snapshots --- AngularNoNgAttributesSnapshotSerializer.js | 34 ++++++++++++++++++ .../a-bit-more-complex.component.spec.ts.snap | 36 +++++++++++++++++++ .../a-bit-more-complex.component.spec.ts | 34 ++++++++++++++++++ .../a-bit-more-complex.component.ts | 21 +++++++++++ .../child.component.ts | 20 +++++++++++ example/src/app/app.component.css | 0 example/src/app/app.component.ts | 9 ++--- example/src/app/app.module.ts | 6 +++- .../__snapshots__/calc.component.spec.ts.snap | 2 -- example/src/app/calc/calc.component.css | 0 example/src/app/calc/calc.component.ts | 3 +- example/src/app/heroes/heroes.component.css | 1 - example/src/app/heroes/heroes.component.ts | 3 +- .../ng-reflect-as-text.component.spec.ts.snap | 12 +++++++ .../ng-reflect-as-text.component.html | 3 ++ .../ng-reflect-as-text.component.spec.ts | 25 +++++++++++++ .../ng-reflect-as-text.component.ts | 7 ++++ .../simple-with-styles.component.spec.ts.snap | 32 +++++++++++++++++ .../simple-with-styles.component.html | 6 ++++ .../simple-with-styles.component.spec.ts | 26 ++++++++++++++ .../simple-with-styles.component.ts | 11 ++++++ .../simple.component.spec.ts.snap | 11 ++++++ example/src/app/simple/simple.component.css | 0 .../src/app/simple/simple.component.spec.ts | 6 +++- example/src/app/simple/simple.component.ts | 14 ++------ jest-preset.js | 1 + package.json | 1 + 27 files changed, 298 insertions(+), 26 deletions(-) create mode 100644 AngularNoNgAttributesSnapshotSerializer.js create mode 100644 example/src/app/a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap create mode 100644 example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.spec.ts create mode 100644 example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.ts create mode 100644 example/src/app/a-bit-more-complex-component/child.component.ts delete mode 100644 example/src/app/app.component.css delete mode 100644 example/src/app/calc/calc.component.css delete mode 100644 example/src/app/heroes/heroes.component.css create mode 100644 example/src/app/ng-reflect-as-text/__snapshots__/ng-reflect-as-text.component.spec.ts.snap create mode 100644 example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.html create mode 100644 example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.spec.ts create mode 100644 example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.ts create mode 100644 example/src/app/simple-with-styles/__snapshots__/simple-with-styles.component.spec.ts.snap create mode 100644 example/src/app/simple-with-styles/simple-with-styles.component.html create mode 100644 example/src/app/simple-with-styles/simple-with-styles.component.spec.ts create mode 100644 example/src/app/simple-with-styles/simple-with-styles.component.ts delete mode 100644 example/src/app/simple/simple.component.css diff --git a/AngularNoNgAttributesSnapshotSerializer.js b/AngularNoNgAttributesSnapshotSerializer.js new file mode 100644 index 0000000000..5a713f6f0f --- /dev/null +++ b/AngularNoNgAttributesSnapshotSerializer.js @@ -0,0 +1,34 @@ +'use strict'; + +const jestDOMElementSerializer = require('pretty-format').plugins.DOMElement; + +const attributesToRemovePatterns = ['ng-reflect', '_nghost', '_ngcontent', 'ng-version']; + +const serialize = (node, ...rest) => { + const nodeCopy = node.cloneNode(true); + Object.values(nodeCopy.attributes) + .map(attribute => attribute.name) + .filter(attributeName => + attributesToRemovePatterns + .some(removeAttributePattern => attributeName.startsWith(removeAttributePattern)) + ) + .forEach(attributeNameToRemove => nodeCopy.attributes.removeNamedItem(attributeNameToRemove)); + + return jestDOMElementSerializer.serialize(nodeCopy, ...rest); +}; + +const serializeTestFn = (val) => { + return val.attributes !== undefined && Object.values(val.attributes) + .map(attribute => attribute.name) + .some(attributeName => + attributesToRemovePatterns + .some(remotePattern => attributeName.startsWith(remotePattern)) + ) +}; +const test = val => + jestDOMElementSerializer.test(val) && serializeTestFn(val); + +module.exports = { + serialize: serialize, + test: test +}; diff --git a/example/src/app/a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap b/example/src/app/a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap new file mode 100644 index 0000000000..bad05bb8be --- /dev/null +++ b/example/src/app/a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ABitMoreComplexComponent snapshot test 1`] = ` + +
+ diary works! + +
+ +
+ another case +
+ + some html + +
+
+ one more case case +
+
+ + stubbedBody + +
+
+
+`; diff --git a/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.spec.ts b/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.spec.ts new file mode 100644 index 0000000000..84ced88983 --- /dev/null +++ b/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.spec.ts @@ -0,0 +1,34 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ABitMoreComplexComponent } from './a-bit-more-complex.component'; +import { ChildComponent } from './child.component'; + +describe('ABitMoreComplexComponent', () => { + let component: ABitMoreComplexComponent; + let fixture: ComponentFixture; + + beforeEach( + async(() => { + TestBed.configureTestingModule({ + declarations: [ABitMoreComplexComponent, ChildComponent], + }) + .overrideComponent(ChildComponent, {set: {template: 'stubbedBody'}}) + .compileComponents(); + }), + ); + + beforeEach(() => { + fixture = TestBed.createComponent(ABitMoreComplexComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('snapshot test', () => { + expect(fixture).toMatchSnapshot(); + }); +}); diff --git a/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.ts b/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.ts new file mode 100644 index 0000000000..3f2e0dbf32 --- /dev/null +++ b/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-a-bit-more-complex', + template: ` +
+ diary works! +
+
+
another case
+ some html +
+
one more case case
+
+
+ ` +}) +export class ABitMoreComplexComponent { + someVar = true; + anotherVar = false; +} diff --git a/example/src/app/a-bit-more-complex-component/child.component.ts b/example/src/app/a-bit-more-complex-component/child.component.ts new file mode 100644 index 0000000000..99a9e4bb7c --- /dev/null +++ b/example/src/app/a-bit-more-complex-component/child.component.ts @@ -0,0 +1,20 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-child-component', + template: ` +
+ {{ someInput }} +
+ rly +

complex

+
component +
oh my god!
+
+
+
+ ` +}) +export class ChildComponent { + @Input() someInput = null; +} diff --git a/example/src/app/app.component.css b/example/src/app/app.component.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/example/src/app/app.component.ts b/example/src/app/app.component.ts index 8490388337..30adc92126 100644 --- a/example/src/app/app.component.ts +++ b/example/src/app/app.component.ts @@ -1,19 +1,16 @@ -import {Component, HostBinding, OnInit} from '@angular/core'; +import {Component, HostBinding} from '@angular/core'; import {trigger, transition, style, animate} from '@angular/animations'; @Component({ selector: 'app-root', animations: [slideToLeft()], - templateUrl: './app.component.html', - styleUrls: ['./app.component.css'], + templateUrl: './app.component.html' }) -export class AppComponent implements OnInit{ +export class AppComponent { @HostBinding('@routerTransition') title = 'app works!'; hasClass = true; variableWithPrecedingDolar = 1234; - - ngOnInit() {} } export function slideToLeft() { diff --git a/example/src/app/app.module.ts b/example/src/app/app.module.ts index babd47c6d6..aca65728dc 100644 --- a/example/src/app/app.module.ts +++ b/example/src/app/app.module.ts @@ -8,6 +8,8 @@ import { CalcComponent } from './calc/calc.component'; import { SimpleComponent } from './simple/simple.component'; import { OnPushComponent } from './on-push/on-push.component'; import { HeroesComponent } from './heroes/heroes.component'; +import { SimpleWithStylesComponent } from './simple-with-styles/simple-with-styles.component'; +import { ChildComponent } from './a-bit-more-complex-component/child.component'; @NgModule({ declarations: [ @@ -15,7 +17,9 @@ import { HeroesComponent } from './heroes/heroes.component'; CalcComponent, SimpleComponent, OnPushComponent, - HeroesComponent + HeroesComponent, + SimpleWithStylesComponent, + ChildComponent ], imports: [ BrowserModule, diff --git a/example/src/app/calc/__snapshots__/calc.component.spec.ts.snap b/example/src/app/calc/__snapshots__/calc.component.spec.ts.snap index 17a2085089..f97b8bfd3b 100644 --- a/example/src/app/calc/__snapshots__/calc.component.spec.ts.snap +++ b/example/src/app/calc/__snapshots__/calc.component.spec.ts.snap @@ -8,8 +8,6 @@ exports[`CalcComponent should snap 1`] = ` >

calc works! 1337 another text node test-image-stub

diff --git a/example/src/app/calc/calc.component.css b/example/src/app/calc/calc.component.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/example/src/app/calc/calc.component.ts b/example/src/app/calc/calc.component.ts index 84f5c5f88f..6a69cc6cc3 100644 --- a/example/src/app/calc/calc.component.ts +++ b/example/src/app/calc/calc.component.ts @@ -17,8 +17,7 @@ const image = require('assets/its_something.png'); another text node {{image}}

- `, - styleUrls: ['./calc.component.css'] + ` }) export class CalcComponent implements OnInit { @Input() hasAClass = false; diff --git a/example/src/app/heroes/heroes.component.css b/example/src/app/heroes/heroes.component.css deleted file mode 100644 index c9859da8e1..0000000000 --- a/example/src/app/heroes/heroes.component.css +++ /dev/null @@ -1 +0,0 @@ -/* HeroesComponent's private CSS styles */ diff --git a/example/src/app/heroes/heroes.component.ts b/example/src/app/heroes/heroes.component.ts index 53e952a145..caa1e435e2 100644 --- a/example/src/app/heroes/heroes.component.ts +++ b/example/src/app/heroes/heroes.component.ts @@ -5,8 +5,7 @@ import { HeroService } from '../service/hero.service'; @Component({ selector: 'app-heroes', - templateUrl: './heroes.component.html', - styleUrls: ['./heroes.component.css'] + templateUrl: './heroes.component.html' }) export class HeroesComponent implements OnInit { heroes: Hero[]; diff --git a/example/src/app/ng-reflect-as-text/__snapshots__/ng-reflect-as-text.component.spec.ts.snap b/example/src/app/ng-reflect-as-text/__snapshots__/ng-reflect-as-text.component.spec.ts.snap new file mode 100644 index 0000000000..8d1f5a6626 --- /dev/null +++ b/example/src/app/ng-reflect-as-text/__snapshots__/ng-reflect-as-text.component.spec.ts.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`NgReflectAsTextComponent snapshots 1`] = ` + +

+ ng-reflect-as-text works! + +

+
+`; diff --git a/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.html b/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.html new file mode 100644 index 0000000000..7fe2ffc7e5 --- /dev/null +++ b/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.html @@ -0,0 +1,3 @@ +

+ ng-reflect-as-text works! +

diff --git a/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.spec.ts b/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.spec.ts new file mode 100644 index 0000000000..cc754ead58 --- /dev/null +++ b/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NgReflectAsTextComponent } from './ng-reflect-as-text.component'; + +describe('NgReflectAsTextComponent', () => { + let component: NgReflectAsTextComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NgReflectAsTextComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NgReflectAsTextComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('snapshots', () => { + expect(fixture).toMatchSnapshot(); + }); +}); diff --git a/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.ts b/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.ts new file mode 100644 index 0000000000..228a500796 --- /dev/null +++ b/example/src/app/ng-reflect-as-text/ng-reflect-as-text.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-ng-reflect-as-text', + templateUrl: './ng-reflect-as-text.component.html' +}) +export class NgReflectAsTextComponent {} diff --git a/example/src/app/simple-with-styles/__snapshots__/simple-with-styles.component.spec.ts.snap b/example/src/app/simple-with-styles/__snapshots__/simple-with-styles.component.spec.ts.snap new file mode 100644 index 0000000000..b602dac2bd --- /dev/null +++ b/example/src/app/simple-with-styles/__snapshots__/simple-with-styles.component.spec.ts.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SimpleWithStylesComponent should generate snapshot without nghost/ngcontent 1`] = ` + +

+ simple-with-styles works! + +

+ +
+ +
+ rly +

+ complex +

+
+ component +
+ oh my god! +
+
+
+
+
+
+
+`; diff --git a/example/src/app/simple-with-styles/simple-with-styles.component.html b/example/src/app/simple-with-styles/simple-with-styles.component.html new file mode 100644 index 0000000000..b11a0d21d6 --- /dev/null +++ b/example/src/app/simple-with-styles/simple-with-styles.component.html @@ -0,0 +1,6 @@ +

+ simple-with-styles works! +

+
+ +
diff --git a/example/src/app/simple-with-styles/simple-with-styles.component.spec.ts b/example/src/app/simple-with-styles/simple-with-styles.component.spec.ts new file mode 100644 index 0000000000..59995ba1e2 --- /dev/null +++ b/example/src/app/simple-with-styles/simple-with-styles.component.spec.ts @@ -0,0 +1,26 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SimpleWithStylesComponent } from './simple-with-styles.component'; +import { ChildComponent } from '../a-bit-more-complex-component/child.component'; + +describe('SimpleWithStylesComponent', () => { + let component: SimpleWithStylesComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SimpleWithStylesComponent, ChildComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SimpleWithStylesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should generate snapshot without nghost/ngcontent', () => { + expect(fixture).toMatchSnapshot(); + }); +}); diff --git a/example/src/app/simple-with-styles/simple-with-styles.component.ts b/example/src/app/simple-with-styles/simple-with-styles.component.ts new file mode 100644 index 0000000000..9948242454 --- /dev/null +++ b/example/src/app/simple-with-styles/simple-with-styles.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-simple-with-styles', + templateUrl: './simple-with-styles.component.html', + // we have to setup styles this way, since simple styles/styleUrs properties will be removed (jest does not unit test styles) + ['styles']: [` + .some-class { color: red } + `] +}) +export class SimpleWithStylesComponent {} diff --git a/example/src/app/simple/__snapshots__/simple.component.spec.ts.snap b/example/src/app/simple/__snapshots__/simple.component.spec.ts.snap index 7c20ea59a6..eed2903adc 100644 --- a/example/src/app/simple/__snapshots__/simple.component.spec.ts.snap +++ b/example/src/app/simple/__snapshots__/simple.component.spec.ts.snap @@ -1,5 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`SimpleComponent snapshot on nativeElement should be without ng-version 1`] = ` +
+

+ simple works! + +

+
+`; + exports[`SimpleComponent snapshots 1`] = `

diff --git a/example/src/app/simple/simple.component.css b/example/src/app/simple/simple.component.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/example/src/app/simple/simple.component.spec.ts b/example/src/app/simple/simple.component.spec.ts index 96309e0fdb..e2f450d546 100644 --- a/example/src/app/simple/simple.component.spec.ts +++ b/example/src/app/simple/simple.component.spec.ts @@ -30,5 +30,9 @@ describe('SimpleComponent', () => { it('snapshots', () => { expect(fixture).toMatchSnapshot(); - }) + }); + + it('snapshot on nativeElement should be without ng-version', () => { + expect(fixture.nativeElement).toMatchSnapshot(); + }); }); diff --git a/example/src/app/simple/simple.component.ts b/example/src/app/simple/simple.component.ts index 3690844248..3eeef34e9a 100644 --- a/example/src/app/simple/simple.component.ts +++ b/example/src/app/simple/simple.component.ts @@ -1,15 +1,7 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ selector: 'app-simple', - templateUrl: 'simple.component.html', - styleUrls: ['./simple.component.css'] + templateUrl: 'simple.component.html' }) -export class SimpleComponent implements OnInit { - - constructor() { } - - ngOnInit() { - } - -} +export class SimpleComponent {} diff --git a/jest-preset.js b/jest-preset.js index 2864adddd4..1eabe3fe33 100644 --- a/jest-preset.js +++ b/jest-preset.js @@ -19,6 +19,7 @@ module.exports = { }, transformIgnorePatterns: ['node_modules/(?!@ngrx)'], snapshotSerializers: [ + 'jest-preset-angular/AngularNoNgAttributesSnapshotSerializer.js', 'jest-preset-angular/AngularSnapshotSerializer.js', 'jest-preset-angular/HTMLCommentSerializer.js', ], diff --git a/package.json b/package.json index 6352892ccb..c7e0fc130e 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "license": "MIT", "dependencies": { "jest-environment-jsdom-thirteen": "^1.0.0", + "pretty-format": "^24.0.0", "ts-jest": "^24.0.0" }, "devDependencies": { From e3c86e362f94d4ef1269a7a1596c3a954705d5c0 Mon Sep 17 00:00:00 2001 From: "Vladislav.Sharikov" Date: Thu, 25 Apr 2019 11:36:46 +0300 Subject: [PATCH 02/10] chore(*): ignore .idea files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 744743d7d0..10aa828c4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules InlineHtmlStripStylesTransformer.js *.log +.idea From 8710de44a05b27add73b088c66b98ae11c11ed2f Mon Sep 17 00:00:00 2001 From: Thomas Wirth Date: Thu, 25 Apr 2019 12:14:33 +0200 Subject: [PATCH 03/10] add --no-cache arg to jest test run --- example/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/package.json b/example/package.json index 10e8e6ddef..308957015c 100644 --- a/example/package.json +++ b/example/package.json @@ -8,7 +8,7 @@ "build": "ng build", "test": "jest", "test:watch": "jest --watch", - "test:ci": "jest --runInBand", + "test:ci": "jest --runInBand --no-cache", "test:coverage": "jest --coverage", "lint": "ng lint", "e2e": "ng e2e" From aa334d766789e8b3020743f7ef7d0f196318eb1c Mon Sep 17 00:00:00 2001 From: Thomas Wirth Date: Thu, 25 Apr 2019 14:59:21 +0300 Subject: [PATCH 04/10] fix: disable node_modules cache --- .circleci/config.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b39fd4acd6..a439965131 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,14 +43,15 @@ jobs: steps: - attach_workspace: at: . - - restore_cache: - keys: - - yarn-cache-example-{{ .Branch }}-{{ checksum "yarn.lock" }} - - yarn-cache-example-{{ .Branch }}- + #- restore_cache: + # keys: + # - yarn-cache-example-{{ .Branch }}-{{ checksum "yarn.lock" }} + # - yarn-cache-example-{{ .Branch }}- - run: name: Install Example Dependencies command: | cd example + rm -rf node_modules/jest-preset-angular yarn install --frozen-lockfile - save_cache: key: yarn-cache-example-{{ .Branch }}-{{ checksum "yarn.lock" }} From 9a27a1a1b6ebfc3493a111098a509a06d12661f3 Mon Sep 17 00:00:00 2001 From: "Vladislav.Sharikov" Date: Thu, 25 Apr 2019 19:32:41 +0300 Subject: [PATCH 05/10] docs(*): add information about new NoNgAttributes serializer --- CHANGELOG.md | 2 ++ README.md | 6 ++++-- example/package.json | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8d0b962e3..0c5e4d2a03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Changelog (master) +* Added `AngularNoNgAttributesSnapshotSerializer`. Using this serializer makes snapshots clearer and more human-readable. You have to apply this serializer manually by redefining `snapshotSerializers` `jest` option. + ### v7.0.0 #### Features diff --git a/README.md b/README.md index f9f9128be5..77e12e2fe5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# jest-preset-angular +AngularSnapshotSerializer# jest-preset-angular [![CircleCI Build Status](https://circleci.com/gh/thymikee/jest-preset-angular.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/thymikee/jest-preset-angular) [![NPM version](https://img.shields.io/npm/v/jest-preset-angular.svg)](https://www.npmjs.com/package/jest-preset-angular) [![Greenkeeper badge](https://badges.greenkeeper.io/thymikee/jest-preset-angular.svg)](https://greenkeeper.io/) @@ -69,6 +69,7 @@ module.exports = { }, transformIgnorePatterns: ['node_modules/(?!@ngrx)'], snapshotSerializers: [ + 'jest-preset-angular/AngularNoNgAttributesSnapshotSerializer.js', 'jest-preset-angular/AngularSnapshotSerializer.js', 'jest-preset-angular/HTMLCommentSerializer.js', ], @@ -84,7 +85,8 @@ module.exports = { - `"moduleFileExtensions"` – our modules are TypeScript and JavaScript files - `"moduleNameMapper"` – if you're using absolute imports here's how to tell Jest where to look for them; uses regex - `"setupFilesAfterEnv"` – this is the heart of our config, in this file we'll setup and patch environment within tests are running -- `"transformIgnorePatterns"` – unfortunately some modules (like @ngrx ) are released as TypeScript files, not pure JavaScript; in such cases we cannot ignore them (all node_modules are ignored by default), so they can be transformed through TS compiler like any other module in our project. +- `"transformIgnorePatterns"` – unfortunately some modules (like @ngrx) are released as TypeScript files, not pure JavaScript; in such cases we cannot ignore them (all node_modules are ignored by default), so they can be transformed through TS compiler like any other module in our project. +- `"snapshotSerializers"` - array of serializers which will be applied to snapshot the code. Note: by default angular adds some angular-specific attributes to the code (like `ng-reflect-*`, `ng-version="*"`, `_ngcontent-c*` etc). This package provides serializer to remove such attributes. This makes snapshots cleaner and more human-readable. To remove such specific attributes use `AngularNoNgAttributesSnapshotSerializer` serializer. You need to add `AngularNoNgAttributesSnapshotSerializer` serializer manually (like in `example` application in `package.json`). ## [AST Transformer](https://github.com/thymikee/jest-preset-angular/blob/master/src/InlineHtmlStripStylesTransformer.ts) diff --git a/example/package.json b/example/package.json index 308957015c..0b34fd4482 100644 --- a/example/package.json +++ b/example/package.json @@ -44,6 +44,11 @@ }, "jest": { "preset": "jest-preset-angular", + "snapshotSerializers": [ + "jest-preset-angular/AngularNoNgAttributesSnapshotSerializer.js", + "jest-preset-angular/AngularSnapshotSerializer.js", + "jest-preset-angular/HTMLCommentSerializer.js" + ], "moduleNameMapper": { "\\.(jpg|jpeg|png)$": "/__mocks__/image.js", "^@lib/(.*)$": "/src/lib/$1" From cfe98e15fa9a1c16f2cb308be5cbdb067b089229 Mon Sep 17 00:00:00 2001 From: "Vladislav.Sharikov" Date: Fri, 26 Apr 2019 00:31:31 +0300 Subject: [PATCH 06/10] fix(*): disable new serializer by default --- jest-preset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest-preset.js b/jest-preset.js index 1eabe3fe33..da04315d42 100644 --- a/jest-preset.js +++ b/jest-preset.js @@ -19,7 +19,7 @@ module.exports = { }, transformIgnorePatterns: ['node_modules/(?!@ngrx)'], snapshotSerializers: [ - 'jest-preset-angular/AngularNoNgAttributesSnapshotSerializer.js', + // 'jest-preset-angular/AngularNoNgAttributesSnapshotSerializer.js', 'jest-preset-angular/AngularSnapshotSerializer.js', 'jest-preset-angular/HTMLCommentSerializer.js', ], From d8577b91a67f6770817272938ed2450955a52779 Mon Sep 17 00:00:00 2001 From: "Vladislav.Sharikov" Date: Sat, 27 Apr 2019 14:36:11 +0300 Subject: [PATCH 07/10] refactor(*): rename component --- example/src/app/app.module.ts | 2 +- .../__snapshots__/medium.component.spec.ts.snap} | 6 +++--- .../child.component.ts | 0 .../medium.component.spec.ts} | 12 ++++++------ .../medium.component.ts} | 4 ++-- .../simple-with-styles.component.spec.ts | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) rename example/src/app/{a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap => medium/__snapshots__/medium.component.spec.ts.snap} (82%) rename example/src/app/{a-bit-more-complex-component => medium}/child.component.ts (100%) rename example/src/app/{a-bit-more-complex-component/a-bit-more-complex.component.spec.ts => medium/medium.component.spec.ts} (63%) rename example/src/app/{a-bit-more-complex-component/a-bit-more-complex.component.ts => medium/medium.component.ts} (86%) diff --git a/example/src/app/app.module.ts b/example/src/app/app.module.ts index aca65728dc..f38223b6c2 100644 --- a/example/src/app/app.module.ts +++ b/example/src/app/app.module.ts @@ -9,7 +9,7 @@ import { SimpleComponent } from './simple/simple.component'; import { OnPushComponent } from './on-push/on-push.component'; import { HeroesComponent } from './heroes/heroes.component'; import { SimpleWithStylesComponent } from './simple-with-styles/simple-with-styles.component'; -import { ChildComponent } from './a-bit-more-complex-component/child.component'; +import { ChildComponent } from './medium/child.component'; @NgModule({ declarations: [ diff --git a/example/src/app/a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap b/example/src/app/medium/__snapshots__/medium.component.spec.ts.snap similarity index 82% rename from example/src/app/a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap rename to example/src/app/medium/__snapshots__/medium.component.spec.ts.snap index bad05bb8be..ecd1ec1754 100644 --- a/example/src/app/a-bit-more-complex-component/__snapshots__/a-bit-more-complex.component.spec.ts.snap +++ b/example/src/app/medium/__snapshots__/medium.component.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`ABitMoreComplexComponent snapshot test 1`] = ` - @@ -32,5 +32,5 @@ exports[`ABitMoreComplexComponent snapshot test 1`] = ` - + `; diff --git a/example/src/app/a-bit-more-complex-component/child.component.ts b/example/src/app/medium/child.component.ts similarity index 100% rename from example/src/app/a-bit-more-complex-component/child.component.ts rename to example/src/app/medium/child.component.ts diff --git a/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.spec.ts b/example/src/app/medium/medium.component.spec.ts similarity index 63% rename from example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.spec.ts rename to example/src/app/medium/medium.component.spec.ts index 84ced88983..03ae291b69 100644 --- a/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.spec.ts +++ b/example/src/app/medium/medium.component.spec.ts @@ -1,17 +1,17 @@ /* tslint:disable:no-unused-variable */ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { ABitMoreComplexComponent } from './a-bit-more-complex.component'; +import { MediumComponent } from './medium.component'; import { ChildComponent } from './child.component'; -describe('ABitMoreComplexComponent', () => { - let component: ABitMoreComplexComponent; - let fixture: ComponentFixture; +describe('MediumComponent', () => { + let component: MediumComponent; + let fixture: ComponentFixture; beforeEach( async(() => { TestBed.configureTestingModule({ - declarations: [ABitMoreComplexComponent, ChildComponent], + declarations: [MediumComponent, ChildComponent], }) .overrideComponent(ChildComponent, {set: {template: 'stubbedBody'}}) .compileComponents(); @@ -19,7 +19,7 @@ describe('ABitMoreComplexComponent', () => { ); beforeEach(() => { - fixture = TestBed.createComponent(ABitMoreComplexComponent); + fixture = TestBed.createComponent(MediumComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.ts b/example/src/app/medium/medium.component.ts similarity index 86% rename from example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.ts rename to example/src/app/medium/medium.component.ts index 3f2e0dbf32..1903fbda3f 100644 --- a/example/src/app/a-bit-more-complex-component/a-bit-more-complex.component.ts +++ b/example/src/app/medium/medium.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; @Component({ - selector: 'app-a-bit-more-complex', + selector: 'app-medium', template: `

diary works! @@ -15,7 +15,7 @@ import { Component } from '@angular/core';
` }) -export class ABitMoreComplexComponent { +export class MediumComponent { someVar = true; anotherVar = false; } diff --git a/example/src/app/simple-with-styles/simple-with-styles.component.spec.ts b/example/src/app/simple-with-styles/simple-with-styles.component.spec.ts index 59995ba1e2..dac9bfa469 100644 --- a/example/src/app/simple-with-styles/simple-with-styles.component.spec.ts +++ b/example/src/app/simple-with-styles/simple-with-styles.component.spec.ts @@ -1,7 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SimpleWithStylesComponent } from './simple-with-styles.component'; -import { ChildComponent } from '../a-bit-more-complex-component/child.component'; +import { ChildComponent } from '../medium/child.component'; describe('SimpleWithStylesComponent', () => { let component: SimpleWithStylesComponent; From d656546d44b3b45e467469626f452d8289f1096d Mon Sep 17 00:00:00 2001 From: Thomas Wirth Date: Sat, 27 Apr 2019 22:54:16 +0200 Subject: [PATCH 08/10] chore(ci): fully disable cache to ensure currency --- .circleci/config.yml | 11 ++++++----- CHANGELOG.md | 1 + example/yarn.lock | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a439965131..85ad1852ff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,6 +43,8 @@ jobs: steps: - attach_workspace: at: . + # disabling cache here as it created issues with the preset in the root + # not being used, as older version in cache was available #- restore_cache: # keys: # - yarn-cache-example-{{ .Branch }}-{{ checksum "yarn.lock" }} @@ -51,12 +53,11 @@ jobs: name: Install Example Dependencies command: | cd example - rm -rf node_modules/jest-preset-angular yarn install --frozen-lockfile - - save_cache: - key: yarn-cache-example-{{ .Branch }}-{{ checksum "yarn.lock" }} - paths: - - ./example/node_modules + #- save_cache: + # key: yarn-cache-example-{{ .Branch }}-{{ checksum "yarn.lock" }} + # paths: + # - ./example/node_modules - run: name: Test Example command: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c5e4d2a03..b032817330 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Changelog (master) * Added `AngularNoNgAttributesSnapshotSerializer`. Using this serializer makes snapshots clearer and more human-readable. You have to apply this serializer manually by redefining `snapshotSerializers` `jest` option. +* Fixed a CI cache issue in the example app, which would not always use the current version of the preset in the test runs. ### v7.0.0 diff --git a/example/yarn.lock b/example/yarn.lock index 20cbaf24ed..95e90a4775 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -3953,6 +3953,7 @@ jest-mock@^24.0.0: version "7.0.1" dependencies: jest-environment-jsdom-thirteen "^1.0.0" + pretty-format "^24.0.0" ts-jest "^24.0.0" jest-regex-util@^24.0.0: From a582354de057b7593ddabe56bd9cdfe71462856f Mon Sep 17 00:00:00 2001 From: "Vladislav.Sharikov" Date: Sun, 28 Apr 2019 12:42:11 +0300 Subject: [PATCH 09/10] refactor(*): some points --- AngularNoNgAttributesSnapshotSerializer.js | 18 +++++++----------- README.md | 3 +-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/AngularNoNgAttributesSnapshotSerializer.js b/AngularNoNgAttributesSnapshotSerializer.js index 5a713f6f0f..ed4b66aea7 100644 --- a/AngularNoNgAttributesSnapshotSerializer.js +++ b/AngularNoNgAttributesSnapshotSerializer.js @@ -4,26 +4,22 @@ const jestDOMElementSerializer = require('pretty-format').plugins.DOMElement; const attributesToRemovePatterns = ['ng-reflect', '_nghost', '_ngcontent', 'ng-version']; +const hasAttributesToRemove = (attribute) => + attributesToRemovePatterns + .some(removePattern => attribute.name.startsWith(removePattern)); + const serialize = (node, ...rest) => { const nodeCopy = node.cloneNode(true); Object.values(nodeCopy.attributes) - .map(attribute => attribute.name) - .filter(attributeName => - attributesToRemovePatterns - .some(removeAttributePattern => attributeName.startsWith(removeAttributePattern)) - ) - .forEach(attributeNameToRemove => nodeCopy.attributes.removeNamedItem(attributeNameToRemove)); + .filter(hasAttributesToRemove) + .forEach(attribute => nodeCopy.attributes.removeNamedItem(attribute.name)); return jestDOMElementSerializer.serialize(nodeCopy, ...rest); }; const serializeTestFn = (val) => { return val.attributes !== undefined && Object.values(val.attributes) - .map(attribute => attribute.name) - .some(attributeName => - attributesToRemovePatterns - .some(remotePattern => attributeName.startsWith(remotePattern)) - ) + .some(hasAttributesToRemove) }; const test = val => jestDOMElementSerializer.test(val) && serializeTestFn(val); diff --git a/README.md b/README.md index 77e12e2fe5..2a9b53087a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -AngularSnapshotSerializer# jest-preset-angular +# jest-preset-angular [![CircleCI Build Status](https://circleci.com/gh/thymikee/jest-preset-angular.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/thymikee/jest-preset-angular) [![NPM version](https://img.shields.io/npm/v/jest-preset-angular.svg)](https://www.npmjs.com/package/jest-preset-angular) [![Greenkeeper badge](https://badges.greenkeeper.io/thymikee/jest-preset-angular.svg)](https://greenkeeper.io/) @@ -69,7 +69,6 @@ module.exports = { }, transformIgnorePatterns: ['node_modules/(?!@ngrx)'], snapshotSerializers: [ - 'jest-preset-angular/AngularNoNgAttributesSnapshotSerializer.js', 'jest-preset-angular/AngularSnapshotSerializer.js', 'jest-preset-angular/HTMLCommentSerializer.js', ], From 61ad6a4ffbc38c635c130d9615502c6d0018458c Mon Sep 17 00:00:00 2001 From: Thomas Wirth Date: Sun, 28 Apr 2019 23:07:36 +0200 Subject: [PATCH 10/10] remove --no-cache flag, add serializer config link --- README.md | 2 +- example/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2a9b53087a..6724e1df8c 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ module.exports = { - `"moduleNameMapper"` – if you're using absolute imports here's how to tell Jest where to look for them; uses regex - `"setupFilesAfterEnv"` – this is the heart of our config, in this file we'll setup and patch environment within tests are running - `"transformIgnorePatterns"` – unfortunately some modules (like @ngrx) are released as TypeScript files, not pure JavaScript; in such cases we cannot ignore them (all node_modules are ignored by default), so they can be transformed through TS compiler like any other module in our project. -- `"snapshotSerializers"` - array of serializers which will be applied to snapshot the code. Note: by default angular adds some angular-specific attributes to the code (like `ng-reflect-*`, `ng-version="*"`, `_ngcontent-c*` etc). This package provides serializer to remove such attributes. This makes snapshots cleaner and more human-readable. To remove such specific attributes use `AngularNoNgAttributesSnapshotSerializer` serializer. You need to add `AngularNoNgAttributesSnapshotSerializer` serializer manually (like in `example` application in `package.json`). +- `"snapshotSerializers"` - array of serializers which will be applied to snapshot the code. Note: by default angular adds some angular-specific attributes to the code (like `ng-reflect-*`, `ng-version="*"`, `_ngcontent-c*` etc). This package provides serializer to remove such attributes. This makes snapshots cleaner and more human-readable. To remove such specific attributes use `AngularNoNgAttributesSnapshotSerializer` serializer. You need to add `AngularNoNgAttributesSnapshotSerializer` serializer manually (see [`example` app configuration](https://github.com/thymikee/jest-preset-angular/blob/master/example/package.json#L47-L51)). ## [AST Transformer](https://github.com/thymikee/jest-preset-angular/blob/master/src/InlineHtmlStripStylesTransformer.ts) diff --git a/example/package.json b/example/package.json index 0b34fd4482..605c8fe006 100644 --- a/example/package.json +++ b/example/package.json @@ -8,7 +8,7 @@ "build": "ng build", "test": "jest", "test:watch": "jest --watch", - "test:ci": "jest --runInBand --no-cache", + "test:ci": "jest --runInBand", "test:coverage": "jest --coverage", "lint": "ng lint", "e2e": "ng e2e"