diff --git a/HTMLElementPlugin.js b/HTMLElementPlugin.js
new file mode 100644
index 0000000000..1eaef112f4
--- /dev/null
+++ b/HTMLElementPlugin.js
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ */
+
+'use strict';
+
+function escapeHTML(str) {
+ return str.replace(//g, '>');
+}
+
+const HTML_ELEMENT_REGEXP = /(HTML\w*?Element)/;
+const test = isHTMLElement;
+
+function isHTMLElement(value) {
+ return (
+ value !== undefined &&
+ value !== null &&
+ value.nodeType === 1 &&
+ value.constructor !== undefined &&
+ HTML_ELEMENT_REGEXP.test(value.constructor.name)
+ );
+}
+
+function printChildren(flatChildren, print, indent, colors, opts) {
+ return flatChildren
+ .map(node => {
+ if (typeof node === 'object') {
+ return print(node, print, indent, colors, opts);
+ } else if (typeof node === 'string') {
+ return colors.content.open + escapeHTML(node) + colors.content.close;
+ } else {
+ return print(node);
+ }
+ })
+ .join(opts.edgeSpacing);
+}
+
+function printAttributes(attributes, print, indent, colors, opts) {
+ return attributes
+ .sort()
+ .map(attribute => {
+ return (
+ opts.spacing +
+ indent(colors.prop.open + attribute.name + colors.prop.close + '=') +
+ colors.value.open +
+ `"${attribute.value}"` +
+ colors.value.close
+ );
+ })
+ .join('');
+}
+
+const print = (
+ element,
+ print,
+ indent,
+ opts,
+ colors
+) => {
+ let result = colors.tag.open + '<';
+ const elementName = element.tagName.toLowerCase();
+ result += elementName + colors.tag.close;
+
+ const hasAttributes = element.attributes && element.attributes.length;
+ if (hasAttributes) {
+ const attributes = Array.prototype.slice.call(element.attributes);
+ result += printAttributes(attributes, print, indent, colors, opts);
+ }
+
+ const flatChildren = Array.prototype.slice.call(element.children);
+ if (!flatChildren.length && element.textContent) {
+ flatChildren.push(element.textContent.trim());
+ }
+
+ const closeInNewLine = hasAttributes && !opts.min;
+ if (flatChildren.length) {
+ const children = printChildren(flatChildren, print, indent, colors, opts);
+ result +=
+ colors.tag.open +
+ (closeInNewLine ? '\n' : '') +
+ '>' +
+ colors.tag.close +
+ (children && opts.edgeSpacing + indent(children) + opts.edgeSpacing) +
+ colors.tag.open +
+ '' +
+ elementName +
+ '>' +
+ colors.tag.close;
+ } else {
+ result +=
+ colors.tag.open + (closeInNewLine ? '\n' : ' ') + '/>' + colors.tag.close;
+ }
+
+ return result;
+};
+
+module.exports = ({print, test});
diff --git a/angular-snapshot.js b/angular-snapshot.js
new file mode 100644
index 0000000000..af8716d3eb
--- /dev/null
+++ b/angular-snapshot.js
@@ -0,0 +1,64 @@
+const printAttributes = (val, attributes, print, indent, colors, opts) => {
+ return attributes
+ .sort()
+ .map(attribute => {
+ return (
+ opts.spacing +
+ indent(colors.prop.open + attribute + colors.prop.close + '=') +
+ colors.value.open +
+ (val.componentInstance[attribute] &&
+ val.componentInstance[attribute].constructor
+ ? '{[Function ' +
+ val.componentInstance[attribute].constructor.name +
+ ']}'
+ : `"${val.componentInstance[attribute]}"`) +
+ colors.value.close
+ );
+ })
+ .join('');
+};
+
+const print = (val, print, indent, opts, colors) => {
+ let result = '';
+ let componentAttrs = '';
+
+ const componentName = val.componentRef._elDef.element.name;
+ const componentInstance = print(val.componentInstance);
+ const nodes = val.componentRef._view.nodes
+ .filter(node => node.hasOwnProperty('renderElement'))
+ .map(node => print(node.renderElement))
+ .join('\n');
+
+ const attributes = Object.keys(val.componentInstance);
+
+ if (attributes.length) {
+ componentAttrs += printAttributes(
+ val,
+ attributes,
+ print,
+ indent,
+ colors,
+ opts
+ );
+ }
+
+ return (
+ '<' +
+ componentName +
+ componentAttrs +
+ (componentAttrs.length ? '\n' : '') +
+ '>\n' +
+ indent(nodes) +
+ '\n' +
+ componentName +
+ '>'
+ );
+};
+
+const test = val =>
+ val !== undefined &&
+ val !== null &&
+ typeof val === 'object' &&
+ Object.prototype.hasOwnProperty.call(val, 'componentRef');
+
+module.exports = {print, test};
diff --git a/circle.yml b/circle.yml
index 787c6a21e8..22a8f7ba4e 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1,6 +1,6 @@
machine:
environment:
- YARN_VERSION: 0.20.3
+ YARN_VERSION: 0.22.0
PATH: "${PATH}:${HOME}/.yarn/bin:${HOME}/${CIRCLE_PROJECT_REPONAME}/node_modules/.bin"
node:
version: 7
@@ -20,4 +20,4 @@ dependencies:
test:
override:
- yarn run test:ci
- - yarn link && cd example && yarn run test:ci && yarn run test:coverage
+ - yarn link && cd example && yarn link jest-preset-angular && yarn run test:ci && yarn run test:coverage
diff --git a/example/src/app/__snapshots__/app.component.spec.ts.snap b/example/src/app/__snapshots__/app.component.spec.ts.snap
new file mode 100644
index 0000000000..6f5c0394d6
--- /dev/null
+++ b/example/src/app/__snapshots__/app.component.spec.ts.snap
@@ -0,0 +1,17 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`AppComponent snaps 1`] = `
+
+
+
+ calc works! +
++
calc works!
diff --git a/example/src/app/calc/calc.component.spec.ts b/example/src/app/calc/calc.component.spec.ts index e52a55cba1..31412feeeb 100644 --- a/example/src/app/calc/calc.component.spec.ts +++ b/example/src/app/calc/calc.component.spec.ts @@ -8,9 +8,9 @@ describe('CalcComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ CalcComponent ] + declarations: [CalcComponent] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { @@ -19,7 +19,7 @@ describe('CalcComponent', () => { fixture.detectChanges(); }); - it('should create', () => { - expect(component).toBeTruthy(); + it('should snap', () => { + expect(fixture).toMatchSnapshot(); }); }); diff --git a/example/src/app/calc/calc.component.ts b/example/src/app/calc/calc.component.ts index 915ac80d84..4ec4e7fb54 100644 --- a/example/src/app/calc/calc.component.ts +++ b/example/src/app/calc/calc.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Input } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; @Component({ selector: 'app-calc', @@ -6,10 +7,19 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./calc.component.css'] }) export class CalcComponent implements OnInit { + @Input() hasAClass; + prop1: number; + observable$: Observable