diff --git a/build/tasks/build.js b/build/tasks/build.js index 532ec4d..bf9f6bb 100644 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -9,16 +9,26 @@ var concat = require('gulp-concat'); var insert = require('gulp-insert'); var rename = require('gulp-rename'); var tools = require('aurelia-tools'); +var gulpIgnore = require('gulp-ignore'); var jsName = paths.packageName + '.js'; +function removeDTSPlugin(options) { + var found = options.plugins.find(function(x){ + return x instanceof Array; + }); + + var index = options.plugins.indexOf(found); + options.plugins.splice(index, 1); + return options; +} + gulp.task('build-index', function(){ var importsToAdd = []; - var files = ['component-tester.js'].map(function(file){ - return paths.root + file; - }); - return gulp.src(files) + return gulp.src(paths.source) + .pipe(tools.sortFiles()) + .pipe(gulpIgnore.exclude('aurelia-testing.js')) .pipe(through2.obj(function(file, enc, callback) { file.contents = new Buffer(tools.extractImports(file.contents.toString("utf8"), importsToAdd)); this.push(file); @@ -31,27 +41,33 @@ gulp.task('build-index', function(){ .pipe(gulp.dest(paths.output)); }); +gulp.task('build-es2015-temp', function () { + return gulp.src(paths.output + jsName) + .pipe(to5(assign({}, compilerOptions.commonjs()))) + .pipe(gulp.dest(paths.output + 'temp')); +}); + gulp.task('build-es2015', function () { - return gulp.src(paths.output + jsName) - .pipe(to5(assign({}, compilerOptions.es2015()))) + return gulp.src(paths.source) + .pipe(to5(assign({}, removeDTSPlugin(compilerOptions.es2015())))) .pipe(gulp.dest(paths.output + 'es2015')); }); gulp.task('build-commonjs', function () { - return gulp.src(paths.output + jsName) - .pipe(to5(assign({}, compilerOptions.commonjs()))) + return gulp.src(paths.source) + .pipe(to5(assign({}, removeDTSPlugin(compilerOptions.commonjs())))) .pipe(gulp.dest(paths.output + 'commonjs')); }); gulp.task('build-amd', function () { - return gulp.src(paths.output + jsName) - .pipe(to5(assign({}, compilerOptions.amd()))) + return gulp.src(paths.source) + .pipe(to5(assign({}, removeDTSPlugin(compilerOptions.amd())))) .pipe(gulp.dest(paths.output + 'amd')); }); gulp.task('build-system', function () { - return gulp.src(paths.output + jsName) - .pipe(to5(assign({}, compilerOptions.system()))) + return gulp.src(paths.source) + .pipe(to5(assign({}, removeDTSPlugin(compilerOptions.system())))) .pipe(gulp.dest(paths.output + 'system')); }); @@ -68,7 +84,7 @@ gulp.task('build', function(callback) { return runSequence( 'clean', 'build-index', - ['build-es2015', 'build-commonjs', 'build-amd', 'build-system'], + ['build-es2015-temp', 'build-es2015', 'build-commonjs', 'build-amd', 'build-system'], 'build-dts', callback ); diff --git a/dist/amd/aurelia-testing.d.ts b/dist/amd/aurelia-testing.d.ts index d8d28d3..df1263b 100644 --- a/dist/amd/aurelia-testing.d.ts +++ b/dist/amd/aurelia-testing.d.ts @@ -1,13 +1,62 @@ declare module 'aurelia-testing' { + import * as LogManager from 'aurelia-logging'; + import { + customAttribute, + View, + TargetInstruction + } from 'aurelia-templating'; import { bootstrap } from 'aurelia-bootstrapper'; - import { - View - } from 'aurelia-templating'; import { Aurelia } from 'aurelia-framework'; + import { + inject + } from 'aurelia-dependency-injection'; + import { + DOM + } from 'aurelia-pal'; + + /** + * Attribute to be placed on any HTML element in a view to emit the View instance + * to the debug console, giving you insight into the live View instance, including + * all child views, live bindings, behaviors and more. + */ + export class ViewSpy { + + /** + * Creates a new instance of ViewSpy. + */ + constructor(); + + /** + * Invoked when the target view is created. + * @param view The target view. + */ + created(view: any): any; + + /** + * Invoked when the target view is bound. + * @param bindingContext The target view's binding context. + */ + bind(bindingContext: any): any; + + /** + * Invoked when the target element is attached to the DOM. + */ + attached(): any; + + /** + * Invoked when the target element is detached from the DOM. + */ + detached(): any; + + /** + * Invoked when the target element is unbound. + */ + unbind(): any; + } export const StageComponent: any; export class ComponentTester { bind: ((bindingContext: any) => void); @@ -28,4 +77,19 @@ declare module 'aurelia-testing' { manuallyHandleLifecycle(): ComponentTester; create(): Promise; } + + /** + * Attribute to be placed on any element to have it emit the View Compiler's + * TargetInstruction into the debug console, giving you insight into all the + * parsed bindings, behaviors and event handers for the targeted element. + */ + export class CompileSpy { + + /** + * Creates and instanse of CompileSpy. + * @param element target element on where attribute is placed on. + * @param instruction instructions for how the target element should be enhanced. + */ + constructor(element: any, instruction: any); + } } \ No newline at end of file diff --git a/dist/amd/aurelia-testing.js b/dist/amd/aurelia-testing.js index 930125b..8d08f37 100644 --- a/dist/amd/aurelia-testing.js +++ b/dist/amd/aurelia-testing.js @@ -1,134 +1,11 @@ -define(['exports', 'aurelia-bootstrapper', 'aurelia-templating', 'aurelia-framework'], function (exports, _aureliaBootstrapper, _aureliaTemplating, _aureliaFramework) { +define(['exports'], function (exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); - exports.ComponentTester = exports.StageComponent = undefined; - - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } + exports.configure = configure; + function configure(config) { + config.globalResources('./compile-spy', './view-spy'); } - - var StageComponent = exports.StageComponent = { - withResources: function withResources(resources) { - return new ComponentTester().withResources(resources); - } - }; - - var ComponentTester = exports.ComponentTester = function () { - function ComponentTester() { - _classCallCheck(this, ComponentTester); - - this.configure = function (aurelia) { - return aurelia.use.standardConfiguration(); - }; - - this._resources = []; - } - - ComponentTester.prototype.bootstrap = function bootstrap(configure) { - this.configure = configure; - }; - - ComponentTester.prototype.withResources = function withResources(resources) { - this._resources = resources; - return this; - }; - - ComponentTester.prototype.inView = function inView(html) { - this._html = html; - return this; - }; - - ComponentTester.prototype.boundTo = function boundTo(bindingContext) { - this._bindingContext = bindingContext; - return this; - }; - - ComponentTester.prototype.manuallyHandleLifecycle = function manuallyHandleLifecycle() { - this._prepareLifecycle(); - return this; - }; - - ComponentTester.prototype.create = function create() { - var _this = this; - - return (0, _aureliaBootstrapper.bootstrap)(function (aurelia) { - return Promise.resolve(_this.configure(aurelia)).then(function () { - aurelia.use.globalResources(_this._resources); - return aurelia.start().then(function (a) { - var host = document.createElement('div'); - host.innerHTML = _this._html; - document.body.appendChild(host); - aurelia.enhance(_this._bindingContext, host); - _this._rootView = aurelia.root; - _this.element = host.firstElementChild; - _this.viewModel = _this.element.au.controller.viewModel; - _this.dispose = function () { - return host.parentNode.removeChild(host); - }; - return new Promise(function (resolve) { - return setTimeout(function () { - return resolve(); - }, 0); - }); - }); - }); - }); - }; - - ComponentTester.prototype._prepareLifecycle = function _prepareLifecycle() { - var _this2 = this; - - var bindPrototype = _aureliaTemplating.View.prototype.bind; - _aureliaTemplating.View.prototype.bind = function () {}; - this.bind = function (bindingContext) { - return new Promise(function (resolve) { - _aureliaTemplating.View.prototype.bind = bindPrototype; - if (bindingContext !== undefined) { - _this2._bindingContext = bindingContext; - } - _this2._rootView.bind(_this2._bindingContext); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - var attachedPrototype = _aureliaTemplating.View.prototype.attached; - _aureliaTemplating.View.prototype.attached = function () {}; - this.attached = function () { - return new Promise(function (resolve) { - _aureliaTemplating.View.prototype.attached = attachedPrototype; - _this2._rootView.attached(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - this.detached = function () { - return new Promise(function (resolve) { - _this2._rootView.detached(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - this.unbind = function () { - return new Promise(function (resolve) { - _this2._rootView.unbind(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - }; - - return ComponentTester; - }(); }); \ No newline at end of file diff --git a/dist/amd/compile-spy.js b/dist/amd/compile-spy.js new file mode 100644 index 0000000..5c12a28 --- /dev/null +++ b/dist/amd/compile-spy.js @@ -0,0 +1,41 @@ +define(['exports', 'aurelia-templating', 'aurelia-dependency-injection', 'aurelia-logging', 'aurelia-pal'], function (exports, _aureliaTemplating, _aureliaDependencyInjection, _aureliaLogging, _aureliaPal) { + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.CompileSpy = undefined; + + var LogManager = _interopRequireWildcard(_aureliaLogging); + + function _interopRequireWildcard(obj) { + if (obj && obj.__esModule) { + return obj; + } else { + var newObj = {}; + + if (obj != null) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; + } + } + + newObj.default = obj; + return newObj; + } + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var _dec, _dec2, _class; + + var CompileSpy = exports.CompileSpy = (_dec = (0, _aureliaTemplating.customAttribute)('compile-spy'), _dec2 = (0, _aureliaDependencyInjection.inject)(_aureliaPal.DOM.Element, _aureliaTemplating.TargetInstruction), _dec(_class = _dec2(_class = function CompileSpy(element, instruction) { + _classCallCheck(this, CompileSpy); + + LogManager.getLogger('compile-spy').info(element, instruction); + }) || _class) || _class); +}); \ No newline at end of file diff --git a/dist/amd/component-tester.js b/dist/amd/component-tester.js new file mode 100644 index 0000000..930125b --- /dev/null +++ b/dist/amd/component-tester.js @@ -0,0 +1,134 @@ +define(['exports', 'aurelia-bootstrapper', 'aurelia-templating', 'aurelia-framework'], function (exports, _aureliaBootstrapper, _aureliaTemplating, _aureliaFramework) { + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ComponentTester = exports.StageComponent = undefined; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var StageComponent = exports.StageComponent = { + withResources: function withResources(resources) { + return new ComponentTester().withResources(resources); + } + }; + + var ComponentTester = exports.ComponentTester = function () { + function ComponentTester() { + _classCallCheck(this, ComponentTester); + + this.configure = function (aurelia) { + return aurelia.use.standardConfiguration(); + }; + + this._resources = []; + } + + ComponentTester.prototype.bootstrap = function bootstrap(configure) { + this.configure = configure; + }; + + ComponentTester.prototype.withResources = function withResources(resources) { + this._resources = resources; + return this; + }; + + ComponentTester.prototype.inView = function inView(html) { + this._html = html; + return this; + }; + + ComponentTester.prototype.boundTo = function boundTo(bindingContext) { + this._bindingContext = bindingContext; + return this; + }; + + ComponentTester.prototype.manuallyHandleLifecycle = function manuallyHandleLifecycle() { + this._prepareLifecycle(); + return this; + }; + + ComponentTester.prototype.create = function create() { + var _this = this; + + return (0, _aureliaBootstrapper.bootstrap)(function (aurelia) { + return Promise.resolve(_this.configure(aurelia)).then(function () { + aurelia.use.globalResources(_this._resources); + return aurelia.start().then(function (a) { + var host = document.createElement('div'); + host.innerHTML = _this._html; + document.body.appendChild(host); + aurelia.enhance(_this._bindingContext, host); + _this._rootView = aurelia.root; + _this.element = host.firstElementChild; + _this.viewModel = _this.element.au.controller.viewModel; + _this.dispose = function () { + return host.parentNode.removeChild(host); + }; + return new Promise(function (resolve) { + return setTimeout(function () { + return resolve(); + }, 0); + }); + }); + }); + }); + }; + + ComponentTester.prototype._prepareLifecycle = function _prepareLifecycle() { + var _this2 = this; + + var bindPrototype = _aureliaTemplating.View.prototype.bind; + _aureliaTemplating.View.prototype.bind = function () {}; + this.bind = function (bindingContext) { + return new Promise(function (resolve) { + _aureliaTemplating.View.prototype.bind = bindPrototype; + if (bindingContext !== undefined) { + _this2._bindingContext = bindingContext; + } + _this2._rootView.bind(_this2._bindingContext); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + var attachedPrototype = _aureliaTemplating.View.prototype.attached; + _aureliaTemplating.View.prototype.attached = function () {}; + this.attached = function () { + return new Promise(function (resolve) { + _aureliaTemplating.View.prototype.attached = attachedPrototype; + _this2._rootView.attached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.detached = function () { + return new Promise(function (resolve) { + _this2._rootView.detached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.unbind = function () { + return new Promise(function (resolve) { + _this2._rootView.unbind(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + }; + + return ComponentTester; + }(); +}); \ No newline at end of file diff --git a/dist/amd/view-spy.js b/dist/amd/view-spy.js new file mode 100644 index 0000000..8f4d483 --- /dev/null +++ b/dist/amd/view-spy.js @@ -0,0 +1,74 @@ +define(['exports', 'aurelia-templating', 'aurelia-logging'], function (exports, _aureliaTemplating, _aureliaLogging) { + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ViewSpy = undefined; + + var LogManager = _interopRequireWildcard(_aureliaLogging); + + function _interopRequireWildcard(obj) { + if (obj && obj.__esModule) { + return obj; + } else { + var newObj = {}; + + if (obj != null) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; + } + } + + newObj.default = obj; + return newObj; + } + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var _dec, _class; + + var ViewSpy = exports.ViewSpy = (_dec = (0, _aureliaTemplating.customAttribute)('view-spy'), _dec(_class = function () { + function ViewSpy() { + _classCallCheck(this, ViewSpy); + + this.logger = LogManager.getLogger('view-spy'); + } + + ViewSpy.prototype._log = function _log(lifecycleName, context) { + if (!this.value && lifecycleName === 'created') { + this.logger.info(lifecycleName, this.view); + } else if (this.value && this.value.indexOf(lifecycleName) !== -1) { + this.logger.info(lifecycleName, this.view, context); + } + }; + + ViewSpy.prototype.created = function created(view) { + this.view = view; + this._log('created'); + }; + + ViewSpy.prototype.bind = function bind(bindingContext) { + this._log('bind', bindingContext); + }; + + ViewSpy.prototype.attached = function attached() { + this._log('attached'); + }; + + ViewSpy.prototype.detached = function detached() { + this._log('detached'); + }; + + ViewSpy.prototype.unbind = function unbind() { + this._log('unbind'); + }; + + return ViewSpy; + }()) || _class); +}); \ No newline at end of file diff --git a/dist/aurelia-testing.d.ts b/dist/aurelia-testing.d.ts index d8d28d3..df1263b 100644 --- a/dist/aurelia-testing.d.ts +++ b/dist/aurelia-testing.d.ts @@ -1,13 +1,62 @@ declare module 'aurelia-testing' { + import * as LogManager from 'aurelia-logging'; + import { + customAttribute, + View, + TargetInstruction + } from 'aurelia-templating'; import { bootstrap } from 'aurelia-bootstrapper'; - import { - View - } from 'aurelia-templating'; import { Aurelia } from 'aurelia-framework'; + import { + inject + } from 'aurelia-dependency-injection'; + import { + DOM + } from 'aurelia-pal'; + + /** + * Attribute to be placed on any HTML element in a view to emit the View instance + * to the debug console, giving you insight into the live View instance, including + * all child views, live bindings, behaviors and more. + */ + export class ViewSpy { + + /** + * Creates a new instance of ViewSpy. + */ + constructor(); + + /** + * Invoked when the target view is created. + * @param view The target view. + */ + created(view: any): any; + + /** + * Invoked when the target view is bound. + * @param bindingContext The target view's binding context. + */ + bind(bindingContext: any): any; + + /** + * Invoked when the target element is attached to the DOM. + */ + attached(): any; + + /** + * Invoked when the target element is detached from the DOM. + */ + detached(): any; + + /** + * Invoked when the target element is unbound. + */ + unbind(): any; + } export const StageComponent: any; export class ComponentTester { bind: ((bindingContext: any) => void); @@ -28,4 +77,19 @@ declare module 'aurelia-testing' { manuallyHandleLifecycle(): ComponentTester; create(): Promise; } + + /** + * Attribute to be placed on any element to have it emit the View Compiler's + * TargetInstruction into the debug console, giving you insight into all the + * parsed bindings, behaviors and event handers for the targeted element. + */ + export class CompileSpy { + + /** + * Creates and instanse of CompileSpy. + * @param element target element on where attribute is placed on. + * @param instruction instructions for how the target element should be enhanced. + */ + constructor(element: any, instruction: any); + } } \ No newline at end of file diff --git a/dist/aurelia-testing.js b/dist/aurelia-testing.js index 07777ca..8b76599 100644 --- a/dist/aurelia-testing.js +++ b/dist/aurelia-testing.js @@ -1,6 +1,70 @@ +import * as LogManager from 'aurelia-logging'; +import {customAttribute,View,TargetInstruction} from 'aurelia-templating'; import {bootstrap} from 'aurelia-bootstrapper'; -import {View} from 'aurelia-templating'; import {Aurelia} from 'aurelia-framework'; +import {inject} from 'aurelia-dependency-injection'; +import {DOM} from 'aurelia-pal'; + +/** +* Attribute to be placed on any HTML element in a view to emit the View instance +* to the debug console, giving you insight into the live View instance, including +* all child views, live bindings, behaviors and more. +*/ +@customAttribute('view-spy') +export class ViewSpy { + /** + * Creates a new instance of ViewSpy. + */ + constructor() { + this.logger = LogManager.getLogger('view-spy'); + } + + _log(lifecycleName, context) { + if (!this.value && lifecycleName === 'created' ) { + this.logger.info(lifecycleName, this.view); + } else if (this.value && this.value.indexOf(lifecycleName) !== -1) { + this.logger.info(lifecycleName, this.view, context); + } + } + + /** + * Invoked when the target view is created. + * @param view The target view. + */ + created(view) { + this.view = view; + this._log('created'); + } + + /** + * Invoked when the target view is bound. + * @param bindingContext The target view's binding context. + */ + bind(bindingContext) { + this._log('bind', bindingContext); + } + + /** + * Invoked when the target element is attached to the DOM. + */ + attached() { + this._log('attached'); + } + + /** + * Invoked when the target element is detached from the DOM. + */ + detached() { + this._log('detached'); + } + + /** + * Invoked when the target element is unbound. + */ + unbind() { + this._log('unbind'); + } +} export const StageComponent = { withResources(resources): ComponentTester { @@ -99,3 +163,21 @@ export class ComponentTester { }); } } + +/** +* Attribute to be placed on any element to have it emit the View Compiler's +* TargetInstruction into the debug console, giving you insight into all the +* parsed bindings, behaviors and event handers for the targeted element. +*/ +@customAttribute('compile-spy') +@inject(DOM.Element, TargetInstruction) +export class CompileSpy { + /** + * Creates and instanse of CompileSpy. + * @param element target element on where attribute is placed on. + * @param instruction instructions for how the target element should be enhanced. + */ + constructor(element, instruction) { + LogManager.getLogger('compile-spy').info(element, instruction); + } +} diff --git a/dist/commonjs/aurelia-testing.d.ts b/dist/commonjs/aurelia-testing.d.ts index d8d28d3..df1263b 100644 --- a/dist/commonjs/aurelia-testing.d.ts +++ b/dist/commonjs/aurelia-testing.d.ts @@ -1,13 +1,62 @@ declare module 'aurelia-testing' { + import * as LogManager from 'aurelia-logging'; + import { + customAttribute, + View, + TargetInstruction + } from 'aurelia-templating'; import { bootstrap } from 'aurelia-bootstrapper'; - import { - View - } from 'aurelia-templating'; import { Aurelia } from 'aurelia-framework'; + import { + inject + } from 'aurelia-dependency-injection'; + import { + DOM + } from 'aurelia-pal'; + + /** + * Attribute to be placed on any HTML element in a view to emit the View instance + * to the debug console, giving you insight into the live View instance, including + * all child views, live bindings, behaviors and more. + */ + export class ViewSpy { + + /** + * Creates a new instance of ViewSpy. + */ + constructor(); + + /** + * Invoked when the target view is created. + * @param view The target view. + */ + created(view: any): any; + + /** + * Invoked when the target view is bound. + * @param bindingContext The target view's binding context. + */ + bind(bindingContext: any): any; + + /** + * Invoked when the target element is attached to the DOM. + */ + attached(): any; + + /** + * Invoked when the target element is detached from the DOM. + */ + detached(): any; + + /** + * Invoked when the target element is unbound. + */ + unbind(): any; + } export const StageComponent: any; export class ComponentTester { bind: ((bindingContext: any) => void); @@ -28,4 +77,19 @@ declare module 'aurelia-testing' { manuallyHandleLifecycle(): ComponentTester; create(): Promise; } + + /** + * Attribute to be placed on any element to have it emit the View Compiler's + * TargetInstruction into the debug console, giving you insight into all the + * parsed bindings, behaviors and event handers for the targeted element. + */ + export class CompileSpy { + + /** + * Creates and instanse of CompileSpy. + * @param element target element on where attribute is placed on. + * @param instruction instructions for how the target element should be enhanced. + */ + constructor(element: any, instruction: any); + } } \ No newline at end of file diff --git a/dist/commonjs/aurelia-testing.js b/dist/commonjs/aurelia-testing.js index ba2155a..6fe85b4 100644 --- a/dist/commonjs/aurelia-testing.js +++ b/dist/commonjs/aurelia-testing.js @@ -3,132 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.ComponentTester = exports.StageComponent = undefined; - -var _aureliaBootstrapper = require('aurelia-bootstrapper'); - -var _aureliaTemplating = require('aurelia-templating'); - -var _aureliaFramework = require('aurelia-framework'); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var StageComponent = exports.StageComponent = { - withResources: function withResources(resources) { - return new ComponentTester().withResources(resources); - } -}; - -var ComponentTester = exports.ComponentTester = function () { - function ComponentTester() { - _classCallCheck(this, ComponentTester); - - this.configure = function (aurelia) { - return aurelia.use.standardConfiguration(); - }; - - this._resources = []; - } - - ComponentTester.prototype.bootstrap = function bootstrap(configure) { - this.configure = configure; - }; - - ComponentTester.prototype.withResources = function withResources(resources) { - this._resources = resources; - return this; - }; - - ComponentTester.prototype.inView = function inView(html) { - this._html = html; - return this; - }; - - ComponentTester.prototype.boundTo = function boundTo(bindingContext) { - this._bindingContext = bindingContext; - return this; - }; - - ComponentTester.prototype.manuallyHandleLifecycle = function manuallyHandleLifecycle() { - this._prepareLifecycle(); - return this; - }; - - ComponentTester.prototype.create = function create() { - var _this = this; - - return (0, _aureliaBootstrapper.bootstrap)(function (aurelia) { - return Promise.resolve(_this.configure(aurelia)).then(function () { - aurelia.use.globalResources(_this._resources); - return aurelia.start().then(function (a) { - var host = document.createElement('div'); - host.innerHTML = _this._html; - document.body.appendChild(host); - aurelia.enhance(_this._bindingContext, host); - _this._rootView = aurelia.root; - _this.element = host.firstElementChild; - _this.viewModel = _this.element.au.controller.viewModel; - _this.dispose = function () { - return host.parentNode.removeChild(host); - }; - return new Promise(function (resolve) { - return setTimeout(function () { - return resolve(); - }, 0); - }); - }); - }); - }); - }; - - ComponentTester.prototype._prepareLifecycle = function _prepareLifecycle() { - var _this2 = this; - - var bindPrototype = _aureliaTemplating.View.prototype.bind; - _aureliaTemplating.View.prototype.bind = function () {}; - this.bind = function (bindingContext) { - return new Promise(function (resolve) { - _aureliaTemplating.View.prototype.bind = bindPrototype; - if (bindingContext !== undefined) { - _this2._bindingContext = bindingContext; - } - _this2._rootView.bind(_this2._bindingContext); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - var attachedPrototype = _aureliaTemplating.View.prototype.attached; - _aureliaTemplating.View.prototype.attached = function () {}; - this.attached = function () { - return new Promise(function (resolve) { - _aureliaTemplating.View.prototype.attached = attachedPrototype; - _this2._rootView.attached(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - this.detached = function () { - return new Promise(function (resolve) { - _this2._rootView.detached(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - this.unbind = function () { - return new Promise(function (resolve) { - _this2._rootView.unbind(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - }; - - return ComponentTester; -}(); \ No newline at end of file +exports.configure = configure; +function configure(config) { + config.globalResources('./compile-spy', './view-spy'); +} \ No newline at end of file diff --git a/dist/commonjs/compile-spy.js b/dist/commonjs/compile-spy.js new file mode 100644 index 0000000..ecd964b --- /dev/null +++ b/dist/commonjs/compile-spy.js @@ -0,0 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CompileSpy = undefined; + +var _dec, _dec2, _class; + +var _aureliaTemplating = require('aurelia-templating'); + +var _aureliaDependencyInjection = require('aurelia-dependency-injection'); + +var _aureliaLogging = require('aurelia-logging'); + +var LogManager = _interopRequireWildcard(_aureliaLogging); + +var _aureliaPal = require('aurelia-pal'); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var CompileSpy = exports.CompileSpy = (_dec = (0, _aureliaTemplating.customAttribute)('compile-spy'), _dec2 = (0, _aureliaDependencyInjection.inject)(_aureliaPal.DOM.Element, _aureliaTemplating.TargetInstruction), _dec(_class = _dec2(_class = function CompileSpy(element, instruction) { + _classCallCheck(this, CompileSpy); + + LogManager.getLogger('compile-spy').info(element, instruction); +}) || _class) || _class); \ No newline at end of file diff --git a/dist/commonjs/component-tester.js b/dist/commonjs/component-tester.js new file mode 100644 index 0000000..ba2155a --- /dev/null +++ b/dist/commonjs/component-tester.js @@ -0,0 +1,134 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ComponentTester = exports.StageComponent = undefined; + +var _aureliaBootstrapper = require('aurelia-bootstrapper'); + +var _aureliaTemplating = require('aurelia-templating'); + +var _aureliaFramework = require('aurelia-framework'); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var StageComponent = exports.StageComponent = { + withResources: function withResources(resources) { + return new ComponentTester().withResources(resources); + } +}; + +var ComponentTester = exports.ComponentTester = function () { + function ComponentTester() { + _classCallCheck(this, ComponentTester); + + this.configure = function (aurelia) { + return aurelia.use.standardConfiguration(); + }; + + this._resources = []; + } + + ComponentTester.prototype.bootstrap = function bootstrap(configure) { + this.configure = configure; + }; + + ComponentTester.prototype.withResources = function withResources(resources) { + this._resources = resources; + return this; + }; + + ComponentTester.prototype.inView = function inView(html) { + this._html = html; + return this; + }; + + ComponentTester.prototype.boundTo = function boundTo(bindingContext) { + this._bindingContext = bindingContext; + return this; + }; + + ComponentTester.prototype.manuallyHandleLifecycle = function manuallyHandleLifecycle() { + this._prepareLifecycle(); + return this; + }; + + ComponentTester.prototype.create = function create() { + var _this = this; + + return (0, _aureliaBootstrapper.bootstrap)(function (aurelia) { + return Promise.resolve(_this.configure(aurelia)).then(function () { + aurelia.use.globalResources(_this._resources); + return aurelia.start().then(function (a) { + var host = document.createElement('div'); + host.innerHTML = _this._html; + document.body.appendChild(host); + aurelia.enhance(_this._bindingContext, host); + _this._rootView = aurelia.root; + _this.element = host.firstElementChild; + _this.viewModel = _this.element.au.controller.viewModel; + _this.dispose = function () { + return host.parentNode.removeChild(host); + }; + return new Promise(function (resolve) { + return setTimeout(function () { + return resolve(); + }, 0); + }); + }); + }); + }); + }; + + ComponentTester.prototype._prepareLifecycle = function _prepareLifecycle() { + var _this2 = this; + + var bindPrototype = _aureliaTemplating.View.prototype.bind; + _aureliaTemplating.View.prototype.bind = function () {}; + this.bind = function (bindingContext) { + return new Promise(function (resolve) { + _aureliaTemplating.View.prototype.bind = bindPrototype; + if (bindingContext !== undefined) { + _this2._bindingContext = bindingContext; + } + _this2._rootView.bind(_this2._bindingContext); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + var attachedPrototype = _aureliaTemplating.View.prototype.attached; + _aureliaTemplating.View.prototype.attached = function () {}; + this.attached = function () { + return new Promise(function (resolve) { + _aureliaTemplating.View.prototype.attached = attachedPrototype; + _this2._rootView.attached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.detached = function () { + return new Promise(function (resolve) { + _this2._rootView.detached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.unbind = function () { + return new Promise(function (resolve) { + _this2._rootView.unbind(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + }; + + return ComponentTester; +}(); \ No newline at end of file diff --git a/dist/commonjs/view-spy.js b/dist/commonjs/view-spy.js new file mode 100644 index 0000000..e258158 --- /dev/null +++ b/dist/commonjs/view-spy.js @@ -0,0 +1,57 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ViewSpy = undefined; + +var _dec, _class; + +var _aureliaTemplating = require('aurelia-templating'); + +var _aureliaLogging = require('aurelia-logging'); + +var LogManager = _interopRequireWildcard(_aureliaLogging); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var ViewSpy = exports.ViewSpy = (_dec = (0, _aureliaTemplating.customAttribute)('view-spy'), _dec(_class = function () { + function ViewSpy() { + _classCallCheck(this, ViewSpy); + + this.logger = LogManager.getLogger('view-spy'); + } + + ViewSpy.prototype._log = function _log(lifecycleName, context) { + if (!this.value && lifecycleName === 'created') { + this.logger.info(lifecycleName, this.view); + } else if (this.value && this.value.indexOf(lifecycleName) !== -1) { + this.logger.info(lifecycleName, this.view, context); + } + }; + + ViewSpy.prototype.created = function created(view) { + this.view = view; + this._log('created'); + }; + + ViewSpy.prototype.bind = function bind(bindingContext) { + this._log('bind', bindingContext); + }; + + ViewSpy.prototype.attached = function attached() { + this._log('attached'); + }; + + ViewSpy.prototype.detached = function detached() { + this._log('detached'); + }; + + ViewSpy.prototype.unbind = function unbind() { + this._log('unbind'); + }; + + return ViewSpy; +}()) || _class); \ No newline at end of file diff --git a/dist/es2015/aurelia-testing.d.ts b/dist/es2015/aurelia-testing.d.ts index d8d28d3..df1263b 100644 --- a/dist/es2015/aurelia-testing.d.ts +++ b/dist/es2015/aurelia-testing.d.ts @@ -1,13 +1,62 @@ declare module 'aurelia-testing' { + import * as LogManager from 'aurelia-logging'; + import { + customAttribute, + View, + TargetInstruction + } from 'aurelia-templating'; import { bootstrap } from 'aurelia-bootstrapper'; - import { - View - } from 'aurelia-templating'; import { Aurelia } from 'aurelia-framework'; + import { + inject + } from 'aurelia-dependency-injection'; + import { + DOM + } from 'aurelia-pal'; + + /** + * Attribute to be placed on any HTML element in a view to emit the View instance + * to the debug console, giving you insight into the live View instance, including + * all child views, live bindings, behaviors and more. + */ + export class ViewSpy { + + /** + * Creates a new instance of ViewSpy. + */ + constructor(); + + /** + * Invoked when the target view is created. + * @param view The target view. + */ + created(view: any): any; + + /** + * Invoked when the target view is bound. + * @param bindingContext The target view's binding context. + */ + bind(bindingContext: any): any; + + /** + * Invoked when the target element is attached to the DOM. + */ + attached(): any; + + /** + * Invoked when the target element is detached from the DOM. + */ + detached(): any; + + /** + * Invoked when the target element is unbound. + */ + unbind(): any; + } export const StageComponent: any; export class ComponentTester { bind: ((bindingContext: any) => void); @@ -28,4 +77,19 @@ declare module 'aurelia-testing' { manuallyHandleLifecycle(): ComponentTester; create(): Promise; } + + /** + * Attribute to be placed on any element to have it emit the View Compiler's + * TargetInstruction into the debug console, giving you insight into all the + * parsed bindings, behaviors and event handers for the targeted element. + */ + export class CompileSpy { + + /** + * Creates and instanse of CompileSpy. + * @param element target element on where attribute is placed on. + * @param instruction instructions for how the target element should be enhanced. + */ + constructor(element: any, instruction: any); + } } \ No newline at end of file diff --git a/dist/es2015/aurelia-testing.js b/dist/es2015/aurelia-testing.js index cc31f98..4954960 100644 --- a/dist/es2015/aurelia-testing.js +++ b/dist/es2015/aurelia-testing.js @@ -1,91 +1,3 @@ -import { bootstrap } from 'aurelia-bootstrapper'; -import { View } from 'aurelia-templating'; -import { Aurelia } from 'aurelia-framework'; - -export const StageComponent = { - withResources(resources) { - return new ComponentTester().withResources(resources); - } -}; - -export let ComponentTester = class ComponentTester { - constructor() { - this.configure = aurelia => aurelia.use.standardConfiguration(); - - this._resources = []; - } - - bootstrap(configure) { - this.configure = configure; - } - - withResources(resources) { - this._resources = resources; - return this; - } - - inView(html) { - this._html = html; - return this; - } - - boundTo(bindingContext) { - this._bindingContext = bindingContext; - return this; - } - - manuallyHandleLifecycle() { - this._prepareLifecycle(); - return this; - } - - create() { - return bootstrap(aurelia => { - return Promise.resolve(this.configure(aurelia)).then(() => { - aurelia.use.globalResources(this._resources); - return aurelia.start().then(a => { - let host = document.createElement('div'); - host.innerHTML = this._html; - document.body.appendChild(host); - aurelia.enhance(this._bindingContext, host); - this._rootView = aurelia.root; - this.element = host.firstElementChild; - this.viewModel = this.element.au.controller.viewModel; - this.dispose = () => host.parentNode.removeChild(host); - return new Promise(resolve => setTimeout(() => resolve(), 0)); - }); - }); - }); - } - - _prepareLifecycle() { - const bindPrototype = View.prototype.bind; - View.prototype.bind = () => {}; - this.bind = bindingContext => new Promise(resolve => { - View.prototype.bind = bindPrototype; - if (bindingContext !== undefined) { - this._bindingContext = bindingContext; - } - this._rootView.bind(this._bindingContext); - setTimeout(() => resolve(), 0); - }); - - const attachedPrototype = View.prototype.attached; - View.prototype.attached = () => {}; - this.attached = () => new Promise(resolve => { - View.prototype.attached = attachedPrototype; - this._rootView.attached(); - setTimeout(() => resolve(), 0); - }); - - this.detached = () => new Promise(resolve => { - this._rootView.detached(); - setTimeout(() => resolve(), 0); - }); - - this.unbind = () => new Promise(resolve => { - this._rootView.unbind(); - setTimeout(() => resolve(), 0); - }); - } -}; \ No newline at end of file +export function configure(config) { + config.globalResources('./compile-spy', './view-spy'); +} \ No newline at end of file diff --git a/dist/es2015/compile-spy.js b/dist/es2015/compile-spy.js new file mode 100644 index 0000000..814a468 --- /dev/null +++ b/dist/es2015/compile-spy.js @@ -0,0 +1,12 @@ +var _dec, _dec2, _class; + +import { customAttribute, TargetInstruction } from 'aurelia-templating'; +import { inject } from 'aurelia-dependency-injection'; +import * as LogManager from 'aurelia-logging'; +import { DOM } from 'aurelia-pal'; + +export let CompileSpy = (_dec = customAttribute('compile-spy'), _dec2 = inject(DOM.Element, TargetInstruction), _dec(_class = _dec2(_class = class CompileSpy { + constructor(element, instruction) { + LogManager.getLogger('compile-spy').info(element, instruction); + } +}) || _class) || _class); \ No newline at end of file diff --git a/dist/es2015/component-tester.js b/dist/es2015/component-tester.js new file mode 100644 index 0000000..cc31f98 --- /dev/null +++ b/dist/es2015/component-tester.js @@ -0,0 +1,91 @@ +import { bootstrap } from 'aurelia-bootstrapper'; +import { View } from 'aurelia-templating'; +import { Aurelia } from 'aurelia-framework'; + +export const StageComponent = { + withResources(resources) { + return new ComponentTester().withResources(resources); + } +}; + +export let ComponentTester = class ComponentTester { + constructor() { + this.configure = aurelia => aurelia.use.standardConfiguration(); + + this._resources = []; + } + + bootstrap(configure) { + this.configure = configure; + } + + withResources(resources) { + this._resources = resources; + return this; + } + + inView(html) { + this._html = html; + return this; + } + + boundTo(bindingContext) { + this._bindingContext = bindingContext; + return this; + } + + manuallyHandleLifecycle() { + this._prepareLifecycle(); + return this; + } + + create() { + return bootstrap(aurelia => { + return Promise.resolve(this.configure(aurelia)).then(() => { + aurelia.use.globalResources(this._resources); + return aurelia.start().then(a => { + let host = document.createElement('div'); + host.innerHTML = this._html; + document.body.appendChild(host); + aurelia.enhance(this._bindingContext, host); + this._rootView = aurelia.root; + this.element = host.firstElementChild; + this.viewModel = this.element.au.controller.viewModel; + this.dispose = () => host.parentNode.removeChild(host); + return new Promise(resolve => setTimeout(() => resolve(), 0)); + }); + }); + }); + } + + _prepareLifecycle() { + const bindPrototype = View.prototype.bind; + View.prototype.bind = () => {}; + this.bind = bindingContext => new Promise(resolve => { + View.prototype.bind = bindPrototype; + if (bindingContext !== undefined) { + this._bindingContext = bindingContext; + } + this._rootView.bind(this._bindingContext); + setTimeout(() => resolve(), 0); + }); + + const attachedPrototype = View.prototype.attached; + View.prototype.attached = () => {}; + this.attached = () => new Promise(resolve => { + View.prototype.attached = attachedPrototype; + this._rootView.attached(); + setTimeout(() => resolve(), 0); + }); + + this.detached = () => new Promise(resolve => { + this._rootView.detached(); + setTimeout(() => resolve(), 0); + }); + + this.unbind = () => new Promise(resolve => { + this._rootView.unbind(); + setTimeout(() => resolve(), 0); + }); + } +}; \ No newline at end of file diff --git a/dist/es2015/view-spy.js b/dist/es2015/view-spy.js new file mode 100644 index 0000000..92e2fb0 --- /dev/null +++ b/dist/es2015/view-spy.js @@ -0,0 +1,39 @@ +var _dec, _class; + +import { customAttribute } from 'aurelia-templating'; +import * as LogManager from 'aurelia-logging'; + +export let ViewSpy = (_dec = customAttribute('view-spy'), _dec(_class = class ViewSpy { + constructor() { + this.logger = LogManager.getLogger('view-spy'); + } + + _log(lifecycleName, context) { + if (!this.value && lifecycleName === 'created') { + this.logger.info(lifecycleName, this.view); + } else if (this.value && this.value.indexOf(lifecycleName) !== -1) { + this.logger.info(lifecycleName, this.view, context); + } + } + + created(view) { + this.view = view; + this._log('created'); + } + + bind(bindingContext) { + this._log('bind', bindingContext); + } + + attached() { + this._log('attached'); + } + + detached() { + this._log('detached'); + } + + unbind() { + this._log('unbind'); + } +}) || _class); \ No newline at end of file diff --git a/dist/system/aurelia-testing.d.ts b/dist/system/aurelia-testing.d.ts index d8d28d3..df1263b 100644 --- a/dist/system/aurelia-testing.d.ts +++ b/dist/system/aurelia-testing.d.ts @@ -1,13 +1,62 @@ declare module 'aurelia-testing' { + import * as LogManager from 'aurelia-logging'; + import { + customAttribute, + View, + TargetInstruction + } from 'aurelia-templating'; import { bootstrap } from 'aurelia-bootstrapper'; - import { - View - } from 'aurelia-templating'; import { Aurelia } from 'aurelia-framework'; + import { + inject + } from 'aurelia-dependency-injection'; + import { + DOM + } from 'aurelia-pal'; + + /** + * Attribute to be placed on any HTML element in a view to emit the View instance + * to the debug console, giving you insight into the live View instance, including + * all child views, live bindings, behaviors and more. + */ + export class ViewSpy { + + /** + * Creates a new instance of ViewSpy. + */ + constructor(); + + /** + * Invoked when the target view is created. + * @param view The target view. + */ + created(view: any): any; + + /** + * Invoked when the target view is bound. + * @param bindingContext The target view's binding context. + */ + bind(bindingContext: any): any; + + /** + * Invoked when the target element is attached to the DOM. + */ + attached(): any; + + /** + * Invoked when the target element is detached from the DOM. + */ + detached(): any; + + /** + * Invoked when the target element is unbound. + */ + unbind(): any; + } export const StageComponent: any; export class ComponentTester { bind: ((bindingContext: any) => void); @@ -28,4 +77,19 @@ declare module 'aurelia-testing' { manuallyHandleLifecycle(): ComponentTester; create(): Promise; } + + /** + * Attribute to be placed on any element to have it emit the View Compiler's + * TargetInstruction into the debug console, giving you insight into all the + * parsed bindings, behaviors and event handers for the targeted element. + */ + export class CompileSpy { + + /** + * Creates and instanse of CompileSpy. + * @param element target element on where attribute is placed on. + * @param instruction instructions for how the target element should be enhanced. + */ + constructor(element: any, instruction: any); + } } \ No newline at end of file diff --git a/dist/system/aurelia-testing.js b/dist/system/aurelia-testing.js index c7f9805..fe14a2c 100644 --- a/dist/system/aurelia-testing.js +++ b/dist/system/aurelia-testing.js @@ -1,146 +1,14 @@ 'use strict'; -System.register(['aurelia-bootstrapper', 'aurelia-templating', 'aurelia-framework'], function (_export, _context) { - var bootstrap, View, Aurelia, StageComponent, ComponentTester; - - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - +System.register([], function (_export, _context) { return { - setters: [function (_aureliaBootstrapper) { - bootstrap = _aureliaBootstrapper.bootstrap; - }, function (_aureliaTemplating) { - View = _aureliaTemplating.View; - }, function (_aureliaFramework) { - Aurelia = _aureliaFramework.Aurelia; - }], + setters: [], execute: function () { - _export('StageComponent', StageComponent = { - withResources: function withResources(resources) { - return new ComponentTester().withResources(resources); - } - }); - - _export('StageComponent', StageComponent); - - _export('ComponentTester', ComponentTester = function () { - function ComponentTester() { - _classCallCheck(this, ComponentTester); - - this.configure = function (aurelia) { - return aurelia.use.standardConfiguration(); - }; - - this._resources = []; - } - - ComponentTester.prototype.bootstrap = function bootstrap(configure) { - this.configure = configure; - }; - - ComponentTester.prototype.withResources = function withResources(resources) { - this._resources = resources; - return this; - }; - - ComponentTester.prototype.inView = function inView(html) { - this._html = html; - return this; - }; - - ComponentTester.prototype.boundTo = function boundTo(bindingContext) { - this._bindingContext = bindingContext; - return this; - }; - - ComponentTester.prototype.manuallyHandleLifecycle = function manuallyHandleLifecycle() { - this._prepareLifecycle(); - return this; - }; - - ComponentTester.prototype.create = function create() { - var _this = this; - - return bootstrap(function (aurelia) { - return Promise.resolve(_this.configure(aurelia)).then(function () { - aurelia.use.globalResources(_this._resources); - return aurelia.start().then(function (a) { - var host = document.createElement('div'); - host.innerHTML = _this._html; - document.body.appendChild(host); - aurelia.enhance(_this._bindingContext, host); - _this._rootView = aurelia.root; - _this.element = host.firstElementChild; - _this.viewModel = _this.element.au.controller.viewModel; - _this.dispose = function () { - return host.parentNode.removeChild(host); - }; - return new Promise(function (resolve) { - return setTimeout(function () { - return resolve(); - }, 0); - }); - }); - }); - }); - }; - - ComponentTester.prototype._prepareLifecycle = function _prepareLifecycle() { - var _this2 = this; - - var bindPrototype = View.prototype.bind; - View.prototype.bind = function () {}; - this.bind = function (bindingContext) { - return new Promise(function (resolve) { - View.prototype.bind = bindPrototype; - if (bindingContext !== undefined) { - _this2._bindingContext = bindingContext; - } - _this2._rootView.bind(_this2._bindingContext); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - var attachedPrototype = View.prototype.attached; - View.prototype.attached = function () {}; - this.attached = function () { - return new Promise(function (resolve) { - View.prototype.attached = attachedPrototype; - _this2._rootView.attached(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - this.detached = function () { - return new Promise(function (resolve) { - _this2._rootView.detached(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - - this.unbind = function () { - return new Promise(function (resolve) { - _this2._rootView.unbind(); - setTimeout(function () { - return resolve(); - }, 0); - }); - }; - }; - - return ComponentTester; - }()); + function configure(config) { + config.globalResources('./compile-spy', './view-spy'); + } - _export('ComponentTester', ComponentTester); + _export('configure', configure); } }; }); \ No newline at end of file diff --git a/dist/system/compile-spy.js b/dist/system/compile-spy.js new file mode 100644 index 0000000..803bbb7 --- /dev/null +++ b/dist/system/compile-spy.js @@ -0,0 +1,33 @@ +'use strict'; + +System.register(['aurelia-templating', 'aurelia-dependency-injection', 'aurelia-logging', 'aurelia-pal'], function (_export, _context) { + var customAttribute, TargetInstruction, inject, LogManager, DOM, _dec, _dec2, _class, CompileSpy; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + return { + setters: [function (_aureliaTemplating) { + customAttribute = _aureliaTemplating.customAttribute; + TargetInstruction = _aureliaTemplating.TargetInstruction; + }, function (_aureliaDependencyInjection) { + inject = _aureliaDependencyInjection.inject; + }, function (_aureliaLogging) { + LogManager = _aureliaLogging; + }, function (_aureliaPal) { + DOM = _aureliaPal.DOM; + }], + execute: function () { + _export('CompileSpy', CompileSpy = (_dec = customAttribute('compile-spy'), _dec2 = inject(DOM.Element, TargetInstruction), _dec(_class = _dec2(_class = function CompileSpy(element, instruction) { + _classCallCheck(this, CompileSpy); + + LogManager.getLogger('compile-spy').info(element, instruction); + }) || _class) || _class)); + + _export('CompileSpy', CompileSpy); + } + }; +}); \ No newline at end of file diff --git a/dist/system/component-tester.js b/dist/system/component-tester.js new file mode 100644 index 0000000..c7f9805 --- /dev/null +++ b/dist/system/component-tester.js @@ -0,0 +1,146 @@ +'use strict'; + +System.register(['aurelia-bootstrapper', 'aurelia-templating', 'aurelia-framework'], function (_export, _context) { + var bootstrap, View, Aurelia, StageComponent, ComponentTester; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + return { + setters: [function (_aureliaBootstrapper) { + bootstrap = _aureliaBootstrapper.bootstrap; + }, function (_aureliaTemplating) { + View = _aureliaTemplating.View; + }, function (_aureliaFramework) { + Aurelia = _aureliaFramework.Aurelia; + }], + execute: function () { + _export('StageComponent', StageComponent = { + withResources: function withResources(resources) { + return new ComponentTester().withResources(resources); + } + }); + + _export('StageComponent', StageComponent); + + _export('ComponentTester', ComponentTester = function () { + function ComponentTester() { + _classCallCheck(this, ComponentTester); + + this.configure = function (aurelia) { + return aurelia.use.standardConfiguration(); + }; + + this._resources = []; + } + + ComponentTester.prototype.bootstrap = function bootstrap(configure) { + this.configure = configure; + }; + + ComponentTester.prototype.withResources = function withResources(resources) { + this._resources = resources; + return this; + }; + + ComponentTester.prototype.inView = function inView(html) { + this._html = html; + return this; + }; + + ComponentTester.prototype.boundTo = function boundTo(bindingContext) { + this._bindingContext = bindingContext; + return this; + }; + + ComponentTester.prototype.manuallyHandleLifecycle = function manuallyHandleLifecycle() { + this._prepareLifecycle(); + return this; + }; + + ComponentTester.prototype.create = function create() { + var _this = this; + + return bootstrap(function (aurelia) { + return Promise.resolve(_this.configure(aurelia)).then(function () { + aurelia.use.globalResources(_this._resources); + return aurelia.start().then(function (a) { + var host = document.createElement('div'); + host.innerHTML = _this._html; + document.body.appendChild(host); + aurelia.enhance(_this._bindingContext, host); + _this._rootView = aurelia.root; + _this.element = host.firstElementChild; + _this.viewModel = _this.element.au.controller.viewModel; + _this.dispose = function () { + return host.parentNode.removeChild(host); + }; + return new Promise(function (resolve) { + return setTimeout(function () { + return resolve(); + }, 0); + }); + }); + }); + }); + }; + + ComponentTester.prototype._prepareLifecycle = function _prepareLifecycle() { + var _this2 = this; + + var bindPrototype = View.prototype.bind; + View.prototype.bind = function () {}; + this.bind = function (bindingContext) { + return new Promise(function (resolve) { + View.prototype.bind = bindPrototype; + if (bindingContext !== undefined) { + _this2._bindingContext = bindingContext; + } + _this2._rootView.bind(_this2._bindingContext); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + var attachedPrototype = View.prototype.attached; + View.prototype.attached = function () {}; + this.attached = function () { + return new Promise(function (resolve) { + View.prototype.attached = attachedPrototype; + _this2._rootView.attached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.detached = function () { + return new Promise(function (resolve) { + _this2._rootView.detached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.unbind = function () { + return new Promise(function (resolve) { + _this2._rootView.unbind(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + }; + + return ComponentTester; + }()); + + _export('ComponentTester', ComponentTester); + } + }; +}); \ No newline at end of file diff --git a/dist/system/view-spy.js b/dist/system/view-spy.js new file mode 100644 index 0000000..24bb9b7 --- /dev/null +++ b/dist/system/view-spy.js @@ -0,0 +1,61 @@ +'use strict'; + +System.register(['aurelia-templating', 'aurelia-logging'], function (_export, _context) { + var customAttribute, LogManager, _dec, _class, ViewSpy; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + return { + setters: [function (_aureliaTemplating) { + customAttribute = _aureliaTemplating.customAttribute; + }, function (_aureliaLogging) { + LogManager = _aureliaLogging; + }], + execute: function () { + _export('ViewSpy', ViewSpy = (_dec = customAttribute('view-spy'), _dec(_class = function () { + function ViewSpy() { + _classCallCheck(this, ViewSpy); + + this.logger = LogManager.getLogger('view-spy'); + } + + ViewSpy.prototype._log = function _log(lifecycleName, context) { + if (!this.value && lifecycleName === 'created') { + this.logger.info(lifecycleName, this.view); + } else if (this.value && this.value.indexOf(lifecycleName) !== -1) { + this.logger.info(lifecycleName, this.view, context); + } + }; + + ViewSpy.prototype.created = function created(view) { + this.view = view; + this._log('created'); + }; + + ViewSpy.prototype.bind = function bind(bindingContext) { + this._log('bind', bindingContext); + }; + + ViewSpy.prototype.attached = function attached() { + this._log('attached'); + }; + + ViewSpy.prototype.detached = function detached() { + this._log('detached'); + }; + + ViewSpy.prototype.unbind = function unbind() { + this._log('unbind'); + }; + + return ViewSpy; + }()) || _class)); + + _export('ViewSpy', ViewSpy); + } + }; +}); \ No newline at end of file diff --git a/dist/temp/aurelia-testing.js b/dist/temp/aurelia-testing.js new file mode 100644 index 0000000..cccd389 --- /dev/null +++ b/dist/temp/aurelia-testing.js @@ -0,0 +1,190 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CompileSpy = exports.ComponentTester = exports.StageComponent = exports.ViewSpy = undefined; + +var _dec, _class, _dec2, _dec3, _class3; + +var _aureliaLogging = require('aurelia-logging'); + +var LogManager = _interopRequireWildcard(_aureliaLogging); + +var _aureliaTemplating = require('aurelia-templating'); + +var _aureliaBootstrapper = require('aurelia-bootstrapper'); + +var _aureliaFramework = require('aurelia-framework'); + +var _aureliaDependencyInjection = require('aurelia-dependency-injection'); + +var _aureliaPal = require('aurelia-pal'); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var ViewSpy = exports.ViewSpy = (_dec = (0, _aureliaTemplating.customAttribute)('view-spy'), _dec(_class = function () { + function ViewSpy() { + _classCallCheck(this, ViewSpy); + + this.logger = LogManager.getLogger('view-spy'); + } + + ViewSpy.prototype._log = function _log(lifecycleName, context) { + if (!this.value && lifecycleName === 'created') { + this.logger.info(lifecycleName, this.view); + } else if (this.value && this.value.indexOf(lifecycleName) !== -1) { + this.logger.info(lifecycleName, this.view, context); + } + }; + + ViewSpy.prototype.created = function created(view) { + this.view = view; + this._log('created'); + }; + + ViewSpy.prototype.bind = function bind(bindingContext) { + this._log('bind', bindingContext); + }; + + ViewSpy.prototype.attached = function attached() { + this._log('attached'); + }; + + ViewSpy.prototype.detached = function detached() { + this._log('detached'); + }; + + ViewSpy.prototype.unbind = function unbind() { + this._log('unbind'); + }; + + return ViewSpy; +}()) || _class); +var StageComponent = exports.StageComponent = { + withResources: function withResources(resources) { + return new ComponentTester().withResources(resources); + } +}; + +var ComponentTester = exports.ComponentTester = function () { + function ComponentTester() { + _classCallCheck(this, ComponentTester); + + this.configure = function (aurelia) { + return aurelia.use.standardConfiguration(); + }; + + this._resources = []; + } + + ComponentTester.prototype.bootstrap = function bootstrap(configure) { + this.configure = configure; + }; + + ComponentTester.prototype.withResources = function withResources(resources) { + this._resources = resources; + return this; + }; + + ComponentTester.prototype.inView = function inView(html) { + this._html = html; + return this; + }; + + ComponentTester.prototype.boundTo = function boundTo(bindingContext) { + this._bindingContext = bindingContext; + return this; + }; + + ComponentTester.prototype.manuallyHandleLifecycle = function manuallyHandleLifecycle() { + this._prepareLifecycle(); + return this; + }; + + ComponentTester.prototype.create = function create() { + var _this = this; + + return (0, _aureliaBootstrapper.bootstrap)(function (aurelia) { + return Promise.resolve(_this.configure(aurelia)).then(function () { + aurelia.use.globalResources(_this._resources); + return aurelia.start().then(function (a) { + var host = document.createElement('div'); + host.innerHTML = _this._html; + document.body.appendChild(host); + aurelia.enhance(_this._bindingContext, host); + _this._rootView = aurelia.root; + _this.element = host.firstElementChild; + _this.viewModel = _this.element.au.controller.viewModel; + _this.dispose = function () { + return host.parentNode.removeChild(host); + }; + return new Promise(function (resolve) { + return setTimeout(function () { + return resolve(); + }, 0); + }); + }); + }); + }); + }; + + ComponentTester.prototype._prepareLifecycle = function _prepareLifecycle() { + var _this2 = this; + + var bindPrototype = _aureliaTemplating.View.prototype.bind; + _aureliaTemplating.View.prototype.bind = function () {}; + this.bind = function (bindingContext) { + return new Promise(function (resolve) { + _aureliaTemplating.View.prototype.bind = bindPrototype; + if (bindingContext !== undefined) { + _this2._bindingContext = bindingContext; + } + _this2._rootView.bind(_this2._bindingContext); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + var attachedPrototype = _aureliaTemplating.View.prototype.attached; + _aureliaTemplating.View.prototype.attached = function () {}; + this.attached = function () { + return new Promise(function (resolve) { + _aureliaTemplating.View.prototype.attached = attachedPrototype; + _this2._rootView.attached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.detached = function () { + return new Promise(function (resolve) { + _this2._rootView.detached(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + + this.unbind = function () { + return new Promise(function (resolve) { + _this2._rootView.unbind(); + setTimeout(function () { + return resolve(); + }, 0); + }); + }; + }; + + return ComponentTester; +}(); + +var CompileSpy = exports.CompileSpy = (_dec2 = (0, _aureliaTemplating.customAttribute)('compile-spy'), _dec3 = (0, _aureliaDependencyInjection.inject)(_aureliaPal.DOM.Element, _aureliaTemplating.TargetInstruction), _dec2(_class3 = _dec3(_class3 = function CompileSpy(element, instruction) { + _classCallCheck(this, CompileSpy); + + LogManager.getLogger('compile-spy').info(element, instruction); +}) || _class3) || _class3); \ No newline at end of file diff --git a/package.json b/package.json index df84ede..4f0e205 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "gulp-bump": "^0.3.1", "gulp-concat": "^2.6.0", "gulp-eslint": "^1.0.0", + "gulp-ignore": "^2.0.1", "gulp-insert": "^0.4.0", "gulp-rename": "^1.2.2", "gulp-typedoc": "^1.2.1", diff --git a/src/aurelia-testing.js b/src/aurelia-testing.js new file mode 100644 index 0000000..d1560fb --- /dev/null +++ b/src/aurelia-testing.js @@ -0,0 +1,6 @@ +export function configure(config) { + config.globalResources( + './compile-spy', + './view-spy' + ); +} diff --git a/src/compile-spy.js b/src/compile-spy.js new file mode 100644 index 0000000..2035688 --- /dev/null +++ b/src/compile-spy.js @@ -0,0 +1,22 @@ +import {customAttribute, TargetInstruction} from 'aurelia-templating'; +import {inject} from 'aurelia-dependency-injection'; +import * as LogManager from 'aurelia-logging'; +import {DOM} from 'aurelia-pal'; + +/** +* Attribute to be placed on any element to have it emit the View Compiler's +* TargetInstruction into the debug console, giving you insight into all the +* parsed bindings, behaviors and event handers for the targeted element. +*/ +@customAttribute('compile-spy') +@inject(DOM.Element, TargetInstruction) +export class CompileSpy { + /** + * Creates and instanse of CompileSpy. + * @param element target element on where attribute is placed on. + * @param instruction instructions for how the target element should be enhanced. + */ + constructor(element, instruction) { + LogManager.getLogger('compile-spy').info(element, instruction); + } +} diff --git a/src/view-spy.js b/src/view-spy.js new file mode 100644 index 0000000..be425cd --- /dev/null +++ b/src/view-spy.js @@ -0,0 +1,63 @@ +import {customAttribute} from 'aurelia-templating'; +import * as LogManager from 'aurelia-logging'; + +/** +* Attribute to be placed on any HTML element in a view to emit the View instance +* to the debug console, giving you insight into the live View instance, including +* all child views, live bindings, behaviors and more. +*/ +@customAttribute('view-spy') +export class ViewSpy { + /** + * Creates a new instance of ViewSpy. + */ + constructor() { + this.logger = LogManager.getLogger('view-spy'); + } + + _log(lifecycleName, context) { + if (!this.value && lifecycleName === 'created' ) { + this.logger.info(lifecycleName, this.view); + } else if (this.value && this.value.indexOf(lifecycleName) !== -1) { + this.logger.info(lifecycleName, this.view, context); + } + } + + /** + * Invoked when the target view is created. + * @param view The target view. + */ + created(view) { + this.view = view; + this._log('created'); + } + + /** + * Invoked when the target view is bound. + * @param bindingContext The target view's binding context. + */ + bind(bindingContext) { + this._log('bind', bindingContext); + } + + /** + * Invoked when the target element is attached to the DOM. + */ + attached() { + this._log('attached'); + } + + /** + * Invoked when the target element is detached from the DOM. + */ + detached() { + this._log('detached'); + } + + /** + * Invoked when the target element is unbound. + */ + unbind() { + this._log('unbind'); + } +}