refactor (benchmarks/): Ts'ifying benchmarks/
Translating AtScript in benchmarks/ to TypeScript.
This commit is contained in:
parent
0b43e3cf32
commit
2b60d1bae1
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.change_detection_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,99 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 change detection benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/change_detection/change_detection_benchmark.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should log ng stats (dynamic, reads)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2ChangeDetectionDynamicReads'],
|
|
||||||
id: 'ng2.changeDetection.dynamic.reads',
|
|
||||||
params: [
|
|
||||||
{name: 'numberOfChecks', value: 900000},
|
|
||||||
{name: 'iterations', value: 20, scale: 'linear'}
|
|
||||||
],
|
|
||||||
microMetrics: {
|
|
||||||
'detectChangesAvg': 'avg time to detect changes (ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log ng stats (dynamic, writes)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2ChangeDetectionDynamicWrites'],
|
|
||||||
id: 'ng2.changeDetection.dynamic.writes',
|
|
||||||
params: [
|
|
||||||
{name: 'numberOfChecks', value: 900000},
|
|
||||||
{name: 'iterations', value: 20, scale: 'linear'}
|
|
||||||
],
|
|
||||||
microMetrics: {
|
|
||||||
'detectChangesAvg': 'avg time to detect changes (ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log ng stats (jit, reads)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2ChangeDetectionJitReads'],
|
|
||||||
id: 'ng2.changeDetection.jit.reads',
|
|
||||||
params: [
|
|
||||||
{name: 'numberOfChecks', value: 900000},
|
|
||||||
{name: 'iterations', value: 20, scale: 'linear'}
|
|
||||||
],
|
|
||||||
microMetrics: {
|
|
||||||
'detectChangesAvg': 'avg time to detect changes (ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log ng stats (jit, writes)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2ChangeDetectionJitWrites'],
|
|
||||||
id: 'ng2.changeDetection.jit.writes',
|
|
||||||
params: [
|
|
||||||
{name: 'numberOfChecks', value: 900000},
|
|
||||||
{name: 'iterations', value: 20, scale: 'linear'}
|
|
||||||
],
|
|
||||||
microMetrics: {
|
|
||||||
'detectChangesAvg': 'avg time to detect changes (ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log baseline stats (create)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#baselineChangeDetectionReads'],
|
|
||||||
id: 'baseline.changeDetection.reads',
|
|
||||||
params: [
|
|
||||||
{name: 'numberOfChecks', value: 900000},
|
|
||||||
{name: 'iterations', value: 20, scale: 'linear'}
|
|
||||||
],
|
|
||||||
microMetrics: {
|
|
||||||
'detectChangesAvg': 'avg time to detect changes (ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log baseline stats (update)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#baselineChangeDetectionWrites'],
|
|
||||||
id: 'baseline.changeDetection.writes',
|
|
||||||
params: [
|
|
||||||
{name: 'numberOfChecks', value: 900000},
|
|
||||||
{name: 'iterations', value: 20, scale: 'linear'}
|
|
||||||
],
|
|
||||||
microMetrics: {
|
|
||||||
'detectChangesAvg': 'avg time to detect changes (ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 change detection benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/change_detection/change_detection_benchmark.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should log ng stats (dynamic, reads)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2ChangeDetectionDynamicReads'],
|
||||||
|
id: 'ng2.changeDetection.dynamic.reads',
|
||||||
|
params: [
|
||||||
|
{name: 'numberOfChecks', value: 900000},
|
||||||
|
{name: 'iterations', value: 20, scale: 'linear'}
|
||||||
|
],
|
||||||
|
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log ng stats (dynamic, writes)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2ChangeDetectionDynamicWrites'],
|
||||||
|
id: 'ng2.changeDetection.dynamic.writes',
|
||||||
|
params: [
|
||||||
|
{name: 'numberOfChecks', value: 900000},
|
||||||
|
{name: 'iterations', value: 20, scale: 'linear'}
|
||||||
|
],
|
||||||
|
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log ng stats (jit, reads)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2ChangeDetectionJitReads'],
|
||||||
|
id: 'ng2.changeDetection.jit.reads',
|
||||||
|
params: [
|
||||||
|
{name: 'numberOfChecks', value: 900000},
|
||||||
|
{name: 'iterations', value: 20, scale: 'linear'}
|
||||||
|
],
|
||||||
|
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log ng stats (jit, writes)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2ChangeDetectionJitWrites'],
|
||||||
|
id: 'ng2.changeDetection.jit.writes',
|
||||||
|
params: [
|
||||||
|
{name: 'numberOfChecks', value: 900000},
|
||||||
|
{name: 'iterations', value: 20, scale: 'linear'}
|
||||||
|
],
|
||||||
|
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log baseline stats (create)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#baselineChangeDetectionReads'],
|
||||||
|
id: 'baseline.changeDetection.reads',
|
||||||
|
params: [
|
||||||
|
{name: 'numberOfChecks', value: 900000},
|
||||||
|
{name: 'iterations', value: 20, scale: 'linear'}
|
||||||
|
],
|
||||||
|
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log baseline stats (update)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#baselineChangeDetectionWrites'],
|
||||||
|
id: 'baseline.changeDetection.writes',
|
||||||
|
params: [
|
||||||
|
{name: 'numberOfChecks', value: 900000},
|
||||||
|
{name: 'iterations', value: 20, scale: 'linear'}
|
||||||
|
],
|
||||||
|
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.compiler_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 compiler benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/compiler/compiler_benchmark.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should log withBindings stats', function(done) {
|
|
||||||
perfUtil.runBenchmark({
|
|
||||||
url: URL,
|
|
||||||
id: 'ng2.compile.withBindings',
|
|
||||||
params: [{
|
|
||||||
name: 'elements', value: 150, scale: 'linear'
|
|
||||||
}],
|
|
||||||
work: function() {
|
|
||||||
browser.executeScript('document.querySelector("#compileWithBindings").click()');
|
|
||||||
browser.sleep(500);
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log noBindings stats', function(done) {
|
|
||||||
perfUtil.runBenchmark({
|
|
||||||
url: URL,
|
|
||||||
id: 'ng2.compile.noBindings',
|
|
||||||
params: [{
|
|
||||||
name: 'elements', value: 150, scale: 'linear'
|
|
||||||
}],
|
|
||||||
work: function() {
|
|
||||||
browser.executeScript('document.querySelector("#compileNoBindings").click()');
|
|
||||||
browser.sleep(500);
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
/// <reference path="../../angular2/typings/angular-protractor/angular-protractor.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 compiler benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/compiler/compiler_benchmark.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should log withBindings stats', function(done) {
|
||||||
|
perfUtil.runBenchmark({
|
||||||
|
url: URL,
|
||||||
|
id: 'ng2.compile.withBindings',
|
||||||
|
params: [{name: 'elements', value: 150, scale: 'linear'}],
|
||||||
|
work: function() {
|
||||||
|
browser.executeScript('document.querySelector("#compileWithBindings").click()');
|
||||||
|
browser.sleep(500);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log noBindings stats', function(done) {
|
||||||
|
perfUtil.runBenchmark({
|
||||||
|
url: URL,
|
||||||
|
id: 'ng2.compile.noBindings',
|
||||||
|
params: [{name: 'elements', value: 150, scale: 'linear'}],
|
||||||
|
work: function() {
|
||||||
|
browser.executeScript('document.querySelector("#compileNoBindings").click()');
|
||||||
|
browser.sleep(500);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.costs_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,44 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 cost benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/costs/index.html';
|
|
||||||
|
|
||||||
// Number of components to create in a single iteration
|
|
||||||
var benchmarkSize = 200;
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should log stats for baseline (plain components)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#reset', '#createPlainComponents'],
|
|
||||||
id: 'ng2.costs.baseline',
|
|
||||||
params: [{
|
|
||||||
name: 'size', value: benchmarkSize, scale: 'linear'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log stats for components with decorators', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#reset', '#createComponentsWithDirectives'],
|
|
||||||
id: 'ng2.costs.decorators',
|
|
||||||
params: [{
|
|
||||||
name: 'size', value: benchmarkSize, scale: 'linear'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log stats for dynamic components', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#reset', '#createDynamicComponents'],
|
|
||||||
id: 'ng2.costs.dynamic',
|
|
||||||
params: [{
|
|
||||||
name: 'size', value: benchmarkSize, scale: 'linear'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 cost benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/costs/index.html';
|
||||||
|
|
||||||
|
// Number of components to create in a single iteration
|
||||||
|
var benchmarkSize = 200;
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should log stats for baseline (plain components)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#reset', '#createPlainComponents'],
|
||||||
|
id: 'ng2.costs.baseline',
|
||||||
|
params: [{name: 'size', value: benchmarkSize, scale: 'linear'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log stats for components with decorators', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#reset', '#createComponentsWithDirectives'],
|
||||||
|
id: 'ng2.costs.decorators',
|
||||||
|
params: [{name: 'size', value: benchmarkSize, scale: 'linear'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log stats for dynamic components', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#reset', '#createDynamicComponents'],
|
||||||
|
id: 'ng2.costs.dynamic',
|
||||||
|
params: [{name: 'size', value: benchmarkSize, scale: 'linear'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.di_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,100 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 di benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/di/di_benchmark.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should log the stats for getByToken', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#getByToken'],
|
|
||||||
id: 'ng2.di.getByToken',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 20000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'injectAvg': 'avg time for injection (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the stats for getByKey', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#getByKey'],
|
|
||||||
id: 'ng2.di.getByKey',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 20000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'injectAvg': 'avg time for injection (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the stats for getChild', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#getChild'],
|
|
||||||
id: 'ng2.di.getChild',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 20000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'injectAvg': 'avg time for getChild (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the stats for instantiate', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#instantiate'],
|
|
||||||
id: 'ng2.di.instantiate',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 10000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'injectAvg': 'avg time for instantiate (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This benchmark measures the cost of creating a new injector with a mix
|
|
||||||
* of binding types: Type, unresolved, unflattened.
|
|
||||||
*/
|
|
||||||
it('should log the stats for createVariety', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#createVariety'],
|
|
||||||
id: 'ng2.di.createVariety',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 10000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'injectAvg': 'avg time for createVariety (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as 'createVariety' benchmark but operates on fully resolved bindings.
|
|
||||||
*/
|
|
||||||
it('should log the stats for createVarietyResolved', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#createVarietyResolved'],
|
|
||||||
id: 'ng2.di.createVarietyResolved',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 10000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'injectAvg': 'avg time for createVarietyResolved (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 di benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/di/di_benchmark.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should log the stats for getByToken', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#getByToken'],
|
||||||
|
id: 'ng2.di.getByToken',
|
||||||
|
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
|
||||||
|
microMetrics: {'injectAvg': 'avg time for injection (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the stats for getByKey', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#getByKey'],
|
||||||
|
id: 'ng2.di.getByKey',
|
||||||
|
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
|
||||||
|
microMetrics: {'injectAvg': 'avg time for injection (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the stats for getChild', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#getChild'],
|
||||||
|
id: 'ng2.di.getChild',
|
||||||
|
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
|
||||||
|
microMetrics: {'injectAvg': 'avg time for getChild (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the stats for instantiate', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#instantiate'],
|
||||||
|
id: 'ng2.di.instantiate',
|
||||||
|
params: [{name: 'iterations', value: 10000, scale: 'linear'}],
|
||||||
|
microMetrics: {'injectAvg': 'avg time for instantiate (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This benchmark measures the cost of creating a new injector with a mix
|
||||||
|
* of binding types: Type, unresolved, unflattened.
|
||||||
|
*/
|
||||||
|
it('should log the stats for createVariety', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#createVariety'],
|
||||||
|
id: 'ng2.di.createVariety',
|
||||||
|
params: [{name: 'iterations', value: 10000, scale: 'linear'}],
|
||||||
|
microMetrics: {'injectAvg': 'avg time for createVariety (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as 'createVariety' benchmark but operates on fully resolved bindings.
|
||||||
|
*/
|
||||||
|
it('should log the stats for createVarietyResolved', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#createVarietyResolved'],
|
||||||
|
id: 'ng2.di.createVarietyResolved',
|
||||||
|
params: [{name: 'iterations', value: 10000, scale: 'linear'}],
|
||||||
|
microMetrics: {'injectAvg': 'avg time for createVarietyResolved (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.element_injector_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 element injector benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/element_injector/element_injector_benchmark.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should log the stats for instantiate', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#instantiate'],
|
|
||||||
id: 'ng2.elementInjector.instantiate',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 20000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'instantiateAvg': 'avg time for injection (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the stats for hydrate', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#hydrate'],
|
|
||||||
id: 'ng2.elementInjector.hydrate',
|
|
||||||
params: [{
|
|
||||||
name: 'iterations', value: 20000, scale: 'linear'
|
|
||||||
}],
|
|
||||||
microMetrics: {
|
|
||||||
'instantiateAvg': 'avg time for injection (in ms)'
|
|
||||||
}
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 element injector benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/element_injector/element_injector_benchmark.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should log the stats for instantiate', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#instantiate'],
|
||||||
|
id: 'ng2.elementInjector.instantiate',
|
||||||
|
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
|
||||||
|
microMetrics: {'instantiateAvg': 'avg time for injection (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the stats for hydrate', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#hydrate'],
|
||||||
|
id: 'ng2.elementInjector.hydrate',
|
||||||
|
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
|
||||||
|
microMetrics: {'instantiateAvg': 'avg time for injection (in ms)'}
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.largetable_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,64 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 largetable benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/largetable/largetable_benchmark.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
// Not yet implemented:
|
|
||||||
// 'ngBind',
|
|
||||||
// 'ngBindOnce',
|
|
||||||
// 'ngBindFn',
|
|
||||||
// 'ngBindFilter',
|
|
||||||
// 'interpolationFilter'
|
|
||||||
|
|
||||||
[
|
|
||||||
'interpolation',
|
|
||||||
'interpolationAttr',
|
|
||||||
'interpolationFn'
|
|
||||||
].forEach(function(benchmarkType) {
|
|
||||||
it('should log the ng stats with: ' + benchmarkType, function(done) {
|
|
||||||
console.log('executing for type', benchmarkType);
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
|
|
||||||
id: 'ng2.largetable.' + benchmarkType,
|
|
||||||
params: [{
|
|
||||||
name: 'rows',
|
|
||||||
value: 20,
|
|
||||||
scale: 'sqrt'
|
|
||||||
},{
|
|
||||||
name: 'columns',
|
|
||||||
value: 20,
|
|
||||||
scale: 'sqrt'
|
|
||||||
},{
|
|
||||||
name: 'benchmarkType',
|
|
||||||
value: benchmarkType
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should log the baseline stats', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#baselineDestroyDom', '#baselineCreateDom'],
|
|
||||||
id: 'baseline.largetable',
|
|
||||||
params: [{
|
|
||||||
name: 'rows',
|
|
||||||
value: 100,
|
|
||||||
scale: 'sqrt'
|
|
||||||
},{
|
|
||||||
name: 'columns',
|
|
||||||
value: 20,
|
|
||||||
scale: 'sqrt'
|
|
||||||
},{
|
|
||||||
name: 'benchmarkType',
|
|
||||||
value: 'baseline'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);;
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 largetable benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/largetable/largetable_benchmark.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
// Not yet implemented:
|
||||||
|
// 'ngBind',
|
||||||
|
// 'ngBindOnce',
|
||||||
|
// 'ngBindFn',
|
||||||
|
// 'ngBindFilter',
|
||||||
|
// 'interpolationFilter'
|
||||||
|
|
||||||
|
['interpolation', 'interpolationAttr', 'interpolationFn'].forEach(function(benchmarkType) {
|
||||||
|
it('should log the ng stats with: ' + benchmarkType, function(done) {
|
||||||
|
console.log('executing for type', benchmarkType);
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
|
||||||
|
id: 'ng2.largetable.' + benchmarkType,
|
||||||
|
params: [
|
||||||
|
{name: 'rows', value: 20, scale: 'sqrt'},
|
||||||
|
{name: 'columns', value: 20, scale: 'sqrt'},
|
||||||
|
{name: 'benchmarkType', value: benchmarkType}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should log the baseline stats', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#baselineDestroyDom', '#baselineCreateDom'],
|
||||||
|
id: 'baseline.largetable',
|
||||||
|
params: [
|
||||||
|
{name: 'rows', value: 100, scale: 'sqrt'},
|
||||||
|
{name: 'columns', value: 20, scale: 'sqrt'},
|
||||||
|
{name: 'benchmarkType', value: 'baseline'}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
;
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.naive_infinite_scroll_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 naive infinite scroll benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/naive_infinite_scroll/index.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
[1, 2, 4].forEach(function(appSize) {
|
|
||||||
it('should run scroll benchmark and collect stats for appSize = ' +
|
|
||||||
appSize, function(done) {
|
|
||||||
perfUtil.runBenchmark({
|
|
||||||
url: URL,
|
|
||||||
id: 'ng2.naive_infinite_scroll',
|
|
||||||
work: function() {
|
|
||||||
$('#reset-btn').click();
|
|
||||||
$('#run-btn').click();
|
|
||||||
browser.wait(() => {
|
|
||||||
return $('#done').getText().then(
|
|
||||||
function() { return true; },
|
|
||||||
function() { return false; });
|
|
||||||
}, 10000);
|
|
||||||
},
|
|
||||||
params: [{
|
|
||||||
name: 'appSize', value: appSize
|
|
||||||
}, {
|
|
||||||
name: 'iterationCount', value: 20, scale: 'linear'
|
|
||||||
}, {
|
|
||||||
name: 'scrollIncrement', value: 40
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
/// <reference path="../../angular2/typings/angular-protractor/angular-protractor.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 naive infinite scroll benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/naive_infinite_scroll/index.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
[1, 2, 4].forEach(function(appSize) {
|
||||||
|
it('should run scroll benchmark and collect stats for appSize = ' + appSize, function(done) {
|
||||||
|
perfUtil.runBenchmark({
|
||||||
|
url: URL,
|
||||||
|
id: 'ng2.naive_infinite_scroll',
|
||||||
|
work: function() {
|
||||||
|
$('#reset-btn').click();
|
||||||
|
$('#run-btn').click();
|
||||||
|
browser.wait(() => {
|
||||||
|
return $('#done').getText().then(function() { return true; },
|
||||||
|
function() { return false; });
|
||||||
|
}, 10000);
|
||||||
|
},
|
||||||
|
params: [
|
||||||
|
{name: 'appSize', value: appSize},
|
||||||
|
{name: 'iterationCount', value: 20, scale: 'linear'},
|
||||||
|
{name: 'scrollIncrement', value: 40}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.naive_infinite_scroll_spec;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,65 +0,0 @@
|
||||||
var testUtil = require('angular2/src/test_lib/e2e_util');
|
|
||||||
|
|
||||||
describe('ng2 naive infinite scroll benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/naive_infinite_scroll/index.html?appSize=3';
|
|
||||||
|
|
||||||
afterEach(testUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should not throw errors', function() {
|
|
||||||
browser.get(URL);
|
|
||||||
var expectedRowCount = 18;
|
|
||||||
var expectedCellsPerRow = 28;
|
|
||||||
var allScrollItems = 'scroll-app #testArea scroll-item';
|
|
||||||
var cells = `${ allScrollItems } .row *`;
|
|
||||||
var stageButtons =
|
|
||||||
`${ allScrollItems } .row stage-buttons button`;
|
|
||||||
|
|
||||||
var count = function(selector) {
|
|
||||||
return browser.executeScript(
|
|
||||||
`return document.querySelectorAll("${ selector }").length;`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var clickFirstOf = function(selector) {
|
|
||||||
return browser.executeScript(
|
|
||||||
`document.querySelector("${ selector }").click();`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var firstTextOf = function(selector) {
|
|
||||||
return browser.executeScript(
|
|
||||||
`return document.querySelector("${ selector }").innerText;`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure rows are rendered
|
|
||||||
count(allScrollItems).then(function(c) {
|
|
||||||
expect(c).toBe(expectedRowCount);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make sure cells are rendered
|
|
||||||
count(cells).then(function(c) {
|
|
||||||
expect(c).toBe(expectedRowCount * expectedCellsPerRow);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Click on first enabled button and verify stage changes
|
|
||||||
firstTextOf(`${ stageButtons }:enabled`).then(function(text) {
|
|
||||||
expect(text).toBe('Pitched');
|
|
||||||
clickFirstOf(`${ stageButtons }:enabled`).then(function() {
|
|
||||||
firstTextOf(`${ stageButtons }:enabled`).then(function(text) {
|
|
||||||
expect(text).toBe('Won');
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
$("#reset-btn").click();
|
|
||||||
$("#run-btn").click();
|
|
||||||
browser.wait(() => {
|
|
||||||
return $('#done').getText().then(
|
|
||||||
function() { return true; },
|
|
||||||
function() { return false; });
|
|
||||||
}, 10000);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
/// <reference path="../../angular2/typings/angular-protractor/angular-protractor.d.ts" />
|
||||||
|
import {afterEach, describe, expect, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var testUtil = require('angular2/src/test_lib/e2e_util');
|
||||||
|
|
||||||
|
describe('ng2 naive infinite scroll benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/naive_infinite_scroll/index.html?appSize=3';
|
||||||
|
|
||||||
|
afterEach(testUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should not throw errors', function() {
|
||||||
|
browser.get(URL);
|
||||||
|
var expectedRowCount = 18;
|
||||||
|
var expectedCellsPerRow = 28;
|
||||||
|
var allScrollItems = 'scroll-app #testArea scroll-item';
|
||||||
|
var cells = `${ allScrollItems } .row *`;
|
||||||
|
var stageButtons = `${ allScrollItems } .row stage-buttons button`;
|
||||||
|
|
||||||
|
var count =
|
||||||
|
function(selector) {
|
||||||
|
return browser.executeScript(`return document.querySelectorAll("${ selector }").length;`);
|
||||||
|
}
|
||||||
|
|
||||||
|
var clickFirstOf =
|
||||||
|
function(selector) {
|
||||||
|
return browser.executeScript(`document.querySelector("${ selector }").click();`);
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstTextOf =
|
||||||
|
function(selector) {
|
||||||
|
return browser.executeScript(`return document.querySelector("${ selector }").innerText;`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure rows are rendered
|
||||||
|
count(allScrollItems)
|
||||||
|
.then(function(c) { expect(c).toBe(expectedRowCount); });
|
||||||
|
|
||||||
|
// Make sure cells are rendered
|
||||||
|
count(cells).then(function(c) { expect(c).toBe(expectedRowCount * expectedCellsPerRow); });
|
||||||
|
|
||||||
|
// Click on first enabled button and verify stage changes
|
||||||
|
firstTextOf(`${ stageButtons }:enabled`)
|
||||||
|
.then(function(text) {
|
||||||
|
expect(text).toBe('Pitched');
|
||||||
|
clickFirstOf(`${ stageButtons }:enabled`)
|
||||||
|
.then(function() {
|
||||||
|
firstTextOf(`${ stageButtons }:enabled`)
|
||||||
|
.then(function(text) { expect(text).toBe('Won'); })
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#reset-btn")
|
||||||
|
.click();
|
||||||
|
$("#run-btn").click();
|
||||||
|
browser.wait(() => {
|
||||||
|
return $('#done').getText().then(function() { return true; }, function() { return false; });
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.selector_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,42 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 selector benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/compiler/selector_benchmark.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should log parse stats', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#parse'],
|
|
||||||
id: 'ng2.selector.parse',
|
|
||||||
params: [{
|
|
||||||
name: 'selectors', value: 10000, scale: 'linear'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log addSelectable stats', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#addSelectable'],
|
|
||||||
id: 'ng2.selector.addSelectable',
|
|
||||||
params: [{
|
|
||||||
name: 'selectors', value: 10000, scale: 'linear'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log match stats', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#match'],
|
|
||||||
id: 'ng2.selector.match',
|
|
||||||
params: [{
|
|
||||||
name: 'selectors', value: 10000, scale: 'linear'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 selector benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/compiler/selector_benchmark.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should log parse stats', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#parse'],
|
||||||
|
id: 'ng2.selector.parse',
|
||||||
|
params: [{name: 'selectors', value: 10000, scale: 'linear'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log addSelectable stats', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#addSelectable'],
|
||||||
|
id: 'ng2.selector.addSelectable',
|
||||||
|
params: [{name: 'selectors', value: 10000, scale: 'linear'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log match stats', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#match'],
|
||||||
|
id: 'ng2.selector.match',
|
||||||
|
params: [{name: 'selectors', value: 10000, scale: 'linear'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
library benchmarks.e2e_test.tree_perf;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
}
|
|
@ -1,70 +0,0 @@
|
||||||
var perfUtil = require('angular2/src/test_lib/perf_util');
|
|
||||||
|
|
||||||
describe('ng2 tree benchmark', function () {
|
|
||||||
|
|
||||||
var URL = 'benchmarks/src/tree/tree_benchmark.html';
|
|
||||||
|
|
||||||
afterEach(perfUtil.verifyNoBrowserErrors);
|
|
||||||
|
|
||||||
it('should log the ng stats with viewcache', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
|
|
||||||
id: 'ng2.tree.create.viewcache',
|
|
||||||
params: [{
|
|
||||||
name: 'depth', value: 9, scale: 'log2'
|
|
||||||
},{
|
|
||||||
name: 'viewcache', value: 'true'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the ng stats without viewcache', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
|
|
||||||
id: 'ng2.tree.create.plain',
|
|
||||||
params: [{
|
|
||||||
name: 'depth', value: 9, scale: 'log2'
|
|
||||||
},{
|
|
||||||
name: 'viewcache', value: 'false'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the ng stats (update)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#ng2CreateDom'],
|
|
||||||
id: 'ng2.tree.update',
|
|
||||||
params: [{
|
|
||||||
name: 'depth', value: 9, scale: 'log2'
|
|
||||||
},{
|
|
||||||
name: 'viewcache', value: 'true'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the baseline stats', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#baselineDestroyDom', '#baselineCreateDom'],
|
|
||||||
id: 'baseline.tree.create',
|
|
||||||
params: [{
|
|
||||||
name: 'depth', value: 9, scale: 'log2'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log the baseline stats (update)', function(done) {
|
|
||||||
perfUtil.runClickBenchmark({
|
|
||||||
url: URL,
|
|
||||||
buttons: ['#baselineCreateDom'],
|
|
||||||
id: 'baseline.tree.update',
|
|
||||||
params: [{
|
|
||||||
name: 'depth', value: 9, scale: 'log2'
|
|
||||||
}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/// <reference path="../../angular2/typings/node/node.d.ts" />
|
||||||
|
import {afterEach, describe, it} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
var perfUtil = require('angular2/src/test_lib/perf_util');
|
||||||
|
|
||||||
|
describe('ng2 tree benchmark', function() {
|
||||||
|
|
||||||
|
var URL = 'benchmarks/src/tree/tree_benchmark.html';
|
||||||
|
|
||||||
|
afterEach(perfUtil.verifyNoBrowserErrors);
|
||||||
|
|
||||||
|
it('should log the ng stats with viewcache', function(done) {
|
||||||
|
perfUtil
|
||||||
|
.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
|
||||||
|
id: 'ng2.tree.create.viewcache',
|
||||||
|
params: [{name: 'depth', value: 9, scale: 'log2'}, {name: 'viewcache', value: 'true'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the ng stats without viewcache', function(done) {
|
||||||
|
perfUtil
|
||||||
|
.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
|
||||||
|
id: 'ng2.tree.create.plain',
|
||||||
|
params: [{name: 'depth', value: 9, scale: 'log2'}, {name: 'viewcache', value: 'false'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the ng stats (update)', function(done) {
|
||||||
|
perfUtil
|
||||||
|
.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#ng2CreateDom'],
|
||||||
|
id: 'ng2.tree.update',
|
||||||
|
params: [{name: 'depth', value: 9, scale: 'log2'}, {name: 'viewcache', value: 'true'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the baseline stats', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#baselineDestroyDom', '#baselineCreateDom'],
|
||||||
|
id: 'baseline.tree.create',
|
||||||
|
params: [{name: 'depth', value: 9, scale: 'log2'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log the baseline stats (update)', function(done) {
|
||||||
|
perfUtil.runClickBenchmark({
|
||||||
|
url: URL,
|
||||||
|
buttons: ['#baselineCreateDom'],
|
||||||
|
id: 'baseline.tree.update',
|
||||||
|
params: [{name: 'depth', value: 9, scale: 'log2'}]
|
||||||
|
})
|
||||||
|
.then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -1,320 +0,0 @@
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
|
||||||
import {isPresent, isJsObject} from 'angular2/src/facade/lang';
|
|
||||||
import {getIntParameter, bindAction, microBenchmark} from 'angular2/src/test_lib/benchmark_util';
|
|
||||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Lexer,
|
|
||||||
Parser,
|
|
||||||
ChangeDispatcher,
|
|
||||||
ChangeDetection,
|
|
||||||
DynamicChangeDetection,
|
|
||||||
JitChangeDetection,
|
|
||||||
ChangeDetectorDefinition,
|
|
||||||
BindingRecord,
|
|
||||||
DirectiveRecord,
|
|
||||||
DirectiveIndex,
|
|
||||||
DEFAULT
|
|
||||||
} from 'angular2/change_detection';
|
|
||||||
|
|
||||||
|
|
||||||
// ---- SHARED
|
|
||||||
|
|
||||||
class Obj {
|
|
||||||
field0;
|
|
||||||
field1;
|
|
||||||
field2;
|
|
||||||
field3;
|
|
||||||
field4;
|
|
||||||
field5;
|
|
||||||
field6;
|
|
||||||
field7;
|
|
||||||
field8;
|
|
||||||
field9;
|
|
||||||
|
|
||||||
|
|
||||||
setField(index, value) {
|
|
||||||
switch (index) {
|
|
||||||
case 0: this.field0 = value; break;
|
|
||||||
case 1: this.field1 = value; break;
|
|
||||||
case 2: this.field2 = value; break;
|
|
||||||
case 3: this.field3 = value; break;
|
|
||||||
case 4: this.field4 = value; break;
|
|
||||||
case 5: this.field5 = value; break;
|
|
||||||
case 6: this.field6 = value; break;
|
|
||||||
case 7: this.field7 = value; break;
|
|
||||||
case 8: this.field8 = value; break;
|
|
||||||
case 9: this.field9 = value; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getField(index) {
|
|
||||||
switch (index) {
|
|
||||||
case 0: return this.field0;
|
|
||||||
case 1: return this.field1;
|
|
||||||
case 2: return this.field2;
|
|
||||||
case 3: return this.field3;
|
|
||||||
case 4: return this.field4;
|
|
||||||
case 5: return this.field5;
|
|
||||||
case 6: return this.field6;
|
|
||||||
case 7: return this.field7;
|
|
||||||
case 8: return this.field8;
|
|
||||||
case 9: return this.field9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Row {
|
|
||||||
obj;
|
|
||||||
targetObj;
|
|
||||||
field0;
|
|
||||||
field1;
|
|
||||||
field2;
|
|
||||||
field3;
|
|
||||||
field4;
|
|
||||||
field5;
|
|
||||||
field6;
|
|
||||||
field7;
|
|
||||||
field8;
|
|
||||||
field9;
|
|
||||||
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createObject() {
|
|
||||||
var obj = new Obj();
|
|
||||||
for (var i = 0; i < 10; ++i) {
|
|
||||||
obj.setField(i, i);
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeObject(object) {
|
|
||||||
for (var i = 0; i < 10; ++i) {
|
|
||||||
object.setField(i, object.getField(i) + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUpReflector() {
|
|
||||||
reflector.registerGetters({
|
|
||||||
'field0': function(obj){return obj.field0},
|
|
||||||
'field1': function(obj){return obj.field1},
|
|
||||||
'field2': function(obj){return obj.field2},
|
|
||||||
'field3': function(obj){return obj.field3},
|
|
||||||
'field4': function(obj){return obj.field4},
|
|
||||||
'field5': function(obj){return obj.field5},
|
|
||||||
'field6': function(obj){return obj.field6},
|
|
||||||
'field7': function(obj){return obj.field7},
|
|
||||||
'field8': function(obj){return obj.field8},
|
|
||||||
'field9': function(obj){return obj.field9}
|
|
||||||
});
|
|
||||||
reflector.registerSetters({
|
|
||||||
'field0': function(obj, v){return obj.field0 = v},
|
|
||||||
'field1': function(obj, v){return obj.field1 = v},
|
|
||||||
'field2': function(obj, v){return obj.field2 = v},
|
|
||||||
'field3': function(obj, v){return obj.field3 = v},
|
|
||||||
'field4': function(obj, v){return obj.field4 = v},
|
|
||||||
'field5': function(obj, v){return obj.field5 = v},
|
|
||||||
'field6': function(obj, v){return obj.field6 = v},
|
|
||||||
'field7': function(obj, v){return obj.field7 = v},
|
|
||||||
'field8': function(obj, v){return obj.field8 = v},
|
|
||||||
'field9': function(obj, v){return obj.field9 = v}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---- BASELINE
|
|
||||||
|
|
||||||
function setUpBaseline(iterations, object) {
|
|
||||||
function createRow(i) {
|
|
||||||
var r = new Row();
|
|
||||||
r.obj = object;
|
|
||||||
r.targetObj = new Obj();
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
var head = createRow(0);
|
|
||||||
var current = head;
|
|
||||||
for (var i = 1; i < iterations; i++) {
|
|
||||||
var newRow = createRow(i);
|
|
||||||
current.next = newRow;
|
|
||||||
current = newRow;
|
|
||||||
}
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkBaselineRow(r) {
|
|
||||||
var obj = r.obj;
|
|
||||||
|
|
||||||
if (obj.field0 !== r.field0) {r.field0 = obj.field0; r.targetObj.field0 = obj.field0; }
|
|
||||||
if (obj.field1 !== r.field1) {r.field1 = obj.field1; r.targetObj.field1 = obj.field1; }
|
|
||||||
if (obj.field2 !== r.field2) {r.field2 = obj.field2; r.targetObj.field2 = obj.field2; }
|
|
||||||
if (obj.field3 !== r.field3) {r.field3 = obj.field3; r.targetObj.field3 = obj.field3; }
|
|
||||||
if (obj.field4 !== r.field4) {r.field4 = obj.field4; r.targetObj.field4 = obj.field4; }
|
|
||||||
if (obj.field5 !== r.field5) {r.field5 = obj.field5; r.targetObj.field5 = obj.field5; }
|
|
||||||
if (obj.field6 !== r.field6) {r.field6 = obj.field6; r.targetObj.field6 = obj.field6; }
|
|
||||||
if (obj.field7 !== r.field7) {r.field7 = obj.field7; r.targetObj.field7 = obj.field7; }
|
|
||||||
if (obj.field8 !== r.field8) {r.field8 = obj.field8; r.targetObj.field8 = obj.field8; }
|
|
||||||
if (obj.field9 !== r.field9) {r.field9 = obj.field9; r.targetObj.field9 = obj.field9; }
|
|
||||||
}
|
|
||||||
|
|
||||||
function runBaselineChangeDetection(baselineHead){
|
|
||||||
var current = baselineHead;
|
|
||||||
while (isPresent(current)) {
|
|
||||||
checkBaselineRow(current);
|
|
||||||
current = current.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function runBaselineReads(baselineHead, numberOfRuns) {
|
|
||||||
for (var i = 0; i < numberOfRuns; ++i) {
|
|
||||||
runBaselineChangeDetection(baselineHead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function runBaselineWrites(baselineHead, numberOfRuns, object) {
|
|
||||||
for (var i = 0; i < numberOfRuns; ++i) {
|
|
||||||
changeObject(object);
|
|
||||||
runBaselineChangeDetection(baselineHead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---- CHANGE DETECTION
|
|
||||||
|
|
||||||
function setUpChangeDetection(changeDetection:ChangeDetection, iterations, object) {
|
|
||||||
var dispatcher = new DummyDispatcher();
|
|
||||||
var parser = new Parser(new Lexer());
|
|
||||||
|
|
||||||
var parentProto = changeDetection.createProtoChangeDetector(new ChangeDetectorDefinition('parent', null, [], [], []));
|
|
||||||
var parentCd = parentProto.instantiate(dispatcher);
|
|
||||||
|
|
||||||
var directiveRecord = new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 0)});
|
|
||||||
var bindings = [
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field0', null), "field0", reflector.setter("field0"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field1', null), "field1", reflector.setter("field1"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field2', null), "field2", reflector.setter("field2"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field3', null), "field3", reflector.setter("field3"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field4', null), "field4", reflector.setter("field4"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field5', null), "field5", reflector.setter("field5"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field6', null), "field6", reflector.setter("field6"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field7', null), "field7", reflector.setter("field7"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field8', null), "field8", reflector.setter("field8"), directiveRecord),
|
|
||||||
BindingRecord.createForDirective(parser.parseBinding('field9', null), "field9", reflector.setter("field9"), directiveRecord)
|
|
||||||
];
|
|
||||||
|
|
||||||
var proto = changeDetection.createProtoChangeDetector(new ChangeDetectorDefinition("proto", null, [], bindings, [directiveRecord]));
|
|
||||||
|
|
||||||
var targetObj = new Obj();
|
|
||||||
for (var i = 0; i < iterations; ++i) {
|
|
||||||
var cd = proto.instantiate(dispatcher);
|
|
||||||
cd.hydrate(object, null, new FakeDirectives(targetObj));
|
|
||||||
parentCd.addChild(cd);
|
|
||||||
}
|
|
||||||
return parentCd;
|
|
||||||
}
|
|
||||||
|
|
||||||
function runChangeDetectionReads(changeDetector, numberOfRuns) {
|
|
||||||
for(var i = 0; i < numberOfRuns; ++i) {
|
|
||||||
changeDetector.detectChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function runChangeDetectionWrites(changeDetector, numberOfRuns, object) {
|
|
||||||
for(var i = 0; i < numberOfRuns; ++i) {
|
|
||||||
changeObject(object);
|
|
||||||
changeDetector.detectChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function main () {
|
|
||||||
BrowserDomAdapter.makeCurrent();
|
|
||||||
var numberOfChecks = getIntParameter('numberOfChecks');
|
|
||||||
var numberOfRuns = getIntParameter('iterations');
|
|
||||||
|
|
||||||
var numberOfChecksPerDetector = 10;
|
|
||||||
var numberOfDetectors = numberOfChecks / numberOfChecksPerDetector / numberOfRuns;
|
|
||||||
|
|
||||||
setUpReflector();
|
|
||||||
var object = createObject()
|
|
||||||
|
|
||||||
// -- BASELINE
|
|
||||||
var baselineHead = setUpBaseline(numberOfDetectors, object);
|
|
||||||
|
|
||||||
runBaselineReads(baselineHead, 1); //warmup
|
|
||||||
|
|
||||||
bindAction(
|
|
||||||
'#baselineChangeDetectionReads',
|
|
||||||
() => microBenchmark('detectChangesAvg', numberOfRuns, () => runBaselineReads(baselineHead, numberOfRuns))
|
|
||||||
);
|
|
||||||
|
|
||||||
bindAction(
|
|
||||||
'#baselineChangeDetectionWrites',
|
|
||||||
() => microBenchmark('detectChangesAvg', numberOfRuns, () => runBaselineWrites(baselineHead, numberOfRuns, object))
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -- DYNAMIC
|
|
||||||
var ng2DynamicChangeDetector = setUpChangeDetection(new DynamicChangeDetection(null), numberOfDetectors, object);
|
|
||||||
|
|
||||||
runChangeDetectionReads(ng2DynamicChangeDetector, 1); //warmup
|
|
||||||
|
|
||||||
bindAction(
|
|
||||||
'#ng2ChangeDetectionDynamicReads',
|
|
||||||
() => microBenchmark('detectChangesAvg', numberOfRuns, () => runChangeDetectionReads(ng2DynamicChangeDetector, numberOfRuns))
|
|
||||||
);
|
|
||||||
|
|
||||||
bindAction(
|
|
||||||
'#ng2ChangeDetectionDynamicWrites',
|
|
||||||
() => microBenchmark('detectChangesAvg', numberOfRuns, () => runChangeDetectionWrites(ng2DynamicChangeDetector, numberOfRuns, object))
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -- JIT
|
|
||||||
// Reenable when we have transformers for Dart
|
|
||||||
if (isJsObject({})) {
|
|
||||||
var ng2JitChangeDetector = setUpChangeDetection(new JitChangeDetection(null), numberOfDetectors, object);
|
|
||||||
|
|
||||||
runChangeDetectionReads(ng2JitChangeDetector, 1); //warmup
|
|
||||||
|
|
||||||
bindAction(
|
|
||||||
'#ng2ChangeDetectionJitReads',
|
|
||||||
() => microBenchmark('detectChangesAvg', numberOfRuns, () => runChangeDetectionReads(ng2JitChangeDetector, numberOfRuns))
|
|
||||||
);
|
|
||||||
|
|
||||||
bindAction(
|
|
||||||
'#ng2ChangeDetectionJitWrites',
|
|
||||||
() => microBenchmark('detectChangesAvg', numberOfRuns, () => runChangeDetectionWrites(ng2JitChangeDetector, numberOfRuns, object))
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
bindAction('#ng2ChangeDetectionJitReads', () => {});
|
|
||||||
bindAction('#ng2ChangeDetectionJitWrites', () => {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeDirectives {
|
|
||||||
targetObj:Obj;
|
|
||||||
|
|
||||||
constructor(targetObj) {
|
|
||||||
this.targetObj = targetObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirectiveFor(record) {
|
|
||||||
return this.targetObj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DummyDispatcher extends ChangeDispatcher {
|
|
||||||
notifyOnBinding(bindingRecord, newValue) {
|
|
||||||
throw "Should not be used";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,383 @@
|
||||||
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
|
import {isPresent, isJsObject} from 'angular2/src/facade/lang';
|
||||||
|
import {getIntParameter, bindAction, microBenchmark} from 'angular2/src/test_lib/benchmark_util';
|
||||||
|
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Lexer,
|
||||||
|
Parser,
|
||||||
|
ChangeDispatcher,
|
||||||
|
ChangeDetection,
|
||||||
|
DynamicChangeDetection,
|
||||||
|
JitChangeDetection,
|
||||||
|
ChangeDetectorDefinition,
|
||||||
|
BindingRecord,
|
||||||
|
DirectiveRecord,
|
||||||
|
DirectiveIndex,
|
||||||
|
DEFAULT
|
||||||
|
} from 'angular2/change_detection';
|
||||||
|
|
||||||
|
|
||||||
|
// ---- SHARED
|
||||||
|
|
||||||
|
class Obj {
|
||||||
|
field0;
|
||||||
|
field1;
|
||||||
|
field2;
|
||||||
|
field3;
|
||||||
|
field4;
|
||||||
|
field5;
|
||||||
|
field6;
|
||||||
|
field7;
|
||||||
|
field8;
|
||||||
|
field9;
|
||||||
|
|
||||||
|
|
||||||
|
setField(index, value) {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
this.field0 = value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this.field1 = value;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.field2 = value;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.field3 = value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.field4 = value;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.field5 = value;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
this.field6 = value;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
this.field7 = value;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
this.field8 = value;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
this.field9 = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getField(index) {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return this.field0;
|
||||||
|
case 1:
|
||||||
|
return this.field1;
|
||||||
|
case 2:
|
||||||
|
return this.field2;
|
||||||
|
case 3:
|
||||||
|
return this.field3;
|
||||||
|
case 4:
|
||||||
|
return this.field4;
|
||||||
|
case 5:
|
||||||
|
return this.field5;
|
||||||
|
case 6:
|
||||||
|
return this.field6;
|
||||||
|
case 7:
|
||||||
|
return this.field7;
|
||||||
|
case 8:
|
||||||
|
return this.field8;
|
||||||
|
case 9:
|
||||||
|
return this.field9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Row {
|
||||||
|
obj;
|
||||||
|
targetObj;
|
||||||
|
field0;
|
||||||
|
field1;
|
||||||
|
field2;
|
||||||
|
field3;
|
||||||
|
field4;
|
||||||
|
field5;
|
||||||
|
field6;
|
||||||
|
field7;
|
||||||
|
field8;
|
||||||
|
field9;
|
||||||
|
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createObject() {
|
||||||
|
var obj = new Obj();
|
||||||
|
for (var i = 0; i < 10; ++i) {
|
||||||
|
obj.setField(i, i);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeObject(object) {
|
||||||
|
for (var i = 0; i < 10; ++i) {
|
||||||
|
object.setField(i, object.getField(i) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUpReflector() {
|
||||||
|
reflector.registerGetters({
|
||||||
|
'field0': function(obj) { return obj.field0 },
|
||||||
|
'field1': function(obj) { return obj.field1 },
|
||||||
|
'field2': function(obj) { return obj.field2 },
|
||||||
|
'field3': function(obj) { return obj.field3 },
|
||||||
|
'field4': function(obj) { return obj.field4 },
|
||||||
|
'field5': function(obj) { return obj.field5 },
|
||||||
|
'field6': function(obj) { return obj.field6 },
|
||||||
|
'field7': function(obj) { return obj.field7 },
|
||||||
|
'field8': function(obj) { return obj.field8 },
|
||||||
|
'field9': function(obj) { return obj.field9 }
|
||||||
|
});
|
||||||
|
reflector.registerSetters({
|
||||||
|
'field0': function(obj, v) { return obj.field0 = v },
|
||||||
|
'field1': function(obj, v) { return obj.field1 = v },
|
||||||
|
'field2': function(obj, v) { return obj.field2 = v },
|
||||||
|
'field3': function(obj, v) { return obj.field3 = v },
|
||||||
|
'field4': function(obj, v) { return obj.field4 = v },
|
||||||
|
'field5': function(obj, v) { return obj.field5 = v },
|
||||||
|
'field6': function(obj, v) { return obj.field6 = v },
|
||||||
|
'field7': function(obj, v) { return obj.field7 = v },
|
||||||
|
'field8': function(obj, v) { return obj.field8 = v },
|
||||||
|
'field9': function(obj, v) { return obj.field9 = v }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ---- BASELINE
|
||||||
|
|
||||||
|
function setUpBaseline(iterations, object) {
|
||||||
|
function createRow(i) {
|
||||||
|
var r = new Row();
|
||||||
|
r.obj = object;
|
||||||
|
r.targetObj = new Obj();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
var head = createRow(0);
|
||||||
|
var current = head;
|
||||||
|
for (var i = 1; i < iterations; i++) {
|
||||||
|
var newRow = createRow(i);
|
||||||
|
current.next = newRow;
|
||||||
|
current = newRow;
|
||||||
|
}
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkBaselineRow(r) {
|
||||||
|
var obj = r.obj;
|
||||||
|
|
||||||
|
if (obj.field0 !== r.field0) {
|
||||||
|
r.field0 = obj.field0;
|
||||||
|
r.targetObj.field0 = obj.field0;
|
||||||
|
}
|
||||||
|
if (obj.field1 !== r.field1) {
|
||||||
|
r.field1 = obj.field1;
|
||||||
|
r.targetObj.field1 = obj.field1;
|
||||||
|
}
|
||||||
|
if (obj.field2 !== r.field2) {
|
||||||
|
r.field2 = obj.field2;
|
||||||
|
r.targetObj.field2 = obj.field2;
|
||||||
|
}
|
||||||
|
if (obj.field3 !== r.field3) {
|
||||||
|
r.field3 = obj.field3;
|
||||||
|
r.targetObj.field3 = obj.field3;
|
||||||
|
}
|
||||||
|
if (obj.field4 !== r.field4) {
|
||||||
|
r.field4 = obj.field4;
|
||||||
|
r.targetObj.field4 = obj.field4;
|
||||||
|
}
|
||||||
|
if (obj.field5 !== r.field5) {
|
||||||
|
r.field5 = obj.field5;
|
||||||
|
r.targetObj.field5 = obj.field5;
|
||||||
|
}
|
||||||
|
if (obj.field6 !== r.field6) {
|
||||||
|
r.field6 = obj.field6;
|
||||||
|
r.targetObj.field6 = obj.field6;
|
||||||
|
}
|
||||||
|
if (obj.field7 !== r.field7) {
|
||||||
|
r.field7 = obj.field7;
|
||||||
|
r.targetObj.field7 = obj.field7;
|
||||||
|
}
|
||||||
|
if (obj.field8 !== r.field8) {
|
||||||
|
r.field8 = obj.field8;
|
||||||
|
r.targetObj.field8 = obj.field8;
|
||||||
|
}
|
||||||
|
if (obj.field9 !== r.field9) {
|
||||||
|
r.field9 = obj.field9;
|
||||||
|
r.targetObj.field9 = obj.field9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runBaselineChangeDetection(baselineHead) {
|
||||||
|
var current = baselineHead;
|
||||||
|
while (isPresent(current)) {
|
||||||
|
checkBaselineRow(current);
|
||||||
|
current = current.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runBaselineReads(baselineHead, numberOfRuns) {
|
||||||
|
for (var i = 0; i < numberOfRuns; ++i) {
|
||||||
|
runBaselineChangeDetection(baselineHead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runBaselineWrites(baselineHead, numberOfRuns, object) {
|
||||||
|
for (var i = 0; i < numberOfRuns; ++i) {
|
||||||
|
changeObject(object);
|
||||||
|
runBaselineChangeDetection(baselineHead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ---- CHANGE DETECTION
|
||||||
|
|
||||||
|
function setUpChangeDetection(changeDetection: ChangeDetection, iterations, object) {
|
||||||
|
var dispatcher = new DummyDispatcher();
|
||||||
|
var parser = new Parser(new Lexer());
|
||||||
|
|
||||||
|
var parentProto = changeDetection.createProtoChangeDetector(
|
||||||
|
new ChangeDetectorDefinition('parent', null, [], [], []));
|
||||||
|
var parentCd = parentProto.instantiate(dispatcher);
|
||||||
|
|
||||||
|
var directiveRecord = new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 0)});
|
||||||
|
var bindings = [
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field0', null), "field0",
|
||||||
|
reflector.setter("field0"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field1', null), "field1",
|
||||||
|
reflector.setter("field1"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field2', null), "field2",
|
||||||
|
reflector.setter("field2"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field3', null), "field3",
|
||||||
|
reflector.setter("field3"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field4', null), "field4",
|
||||||
|
reflector.setter("field4"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field5', null), "field5",
|
||||||
|
reflector.setter("field5"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field6', null), "field6",
|
||||||
|
reflector.setter("field6"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field7', null), "field7",
|
||||||
|
reflector.setter("field7"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field8', null), "field8",
|
||||||
|
reflector.setter("field8"), directiveRecord),
|
||||||
|
BindingRecord.createForDirective(parser.parseBinding('field9', null), "field9",
|
||||||
|
reflector.setter("field9"), directiveRecord)
|
||||||
|
];
|
||||||
|
|
||||||
|
var proto = changeDetection.createProtoChangeDetector(
|
||||||
|
new ChangeDetectorDefinition("proto", null, [], bindings, [directiveRecord]));
|
||||||
|
|
||||||
|
var targetObj = new Obj();
|
||||||
|
for (var i = 0; i < iterations; ++i) {
|
||||||
|
var cd = proto.instantiate(dispatcher);
|
||||||
|
cd.hydrate(object, null, new FakeDirectives(targetObj));
|
||||||
|
parentCd.addChild(cd);
|
||||||
|
}
|
||||||
|
return parentCd;
|
||||||
|
}
|
||||||
|
|
||||||
|
function runChangeDetectionReads(changeDetector, numberOfRuns) {
|
||||||
|
for (var i = 0; i < numberOfRuns; ++i) {
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runChangeDetectionWrites(changeDetector, numberOfRuns, object) {
|
||||||
|
for (var i = 0; i < numberOfRuns; ++i) {
|
||||||
|
changeObject(object);
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
BrowserDomAdapter.makeCurrent();
|
||||||
|
var numberOfChecks = getIntParameter('numberOfChecks');
|
||||||
|
var numberOfRuns = getIntParameter('iterations');
|
||||||
|
|
||||||
|
var numberOfChecksPerDetector = 10;
|
||||||
|
var numberOfDetectors = numberOfChecks / numberOfChecksPerDetector / numberOfRuns;
|
||||||
|
|
||||||
|
setUpReflector();
|
||||||
|
var object = createObject()
|
||||||
|
|
||||||
|
// -- BASELINE
|
||||||
|
var baselineHead = setUpBaseline(numberOfDetectors, object);
|
||||||
|
|
||||||
|
runBaselineReads(baselineHead, 1); // warmup
|
||||||
|
|
||||||
|
bindAction('#baselineChangeDetectionReads',
|
||||||
|
() => microBenchmark('detectChangesAvg', numberOfRuns,
|
||||||
|
() => runBaselineReads(baselineHead, numberOfRuns)));
|
||||||
|
|
||||||
|
bindAction('#baselineChangeDetectionWrites',
|
||||||
|
() => microBenchmark('detectChangesAvg', numberOfRuns,
|
||||||
|
() => runBaselineWrites(baselineHead, numberOfRuns, object)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -- DYNAMIC
|
||||||
|
var ng2DynamicChangeDetector =
|
||||||
|
setUpChangeDetection(new DynamicChangeDetection(null), numberOfDetectors, object);
|
||||||
|
|
||||||
|
runChangeDetectionReads(ng2DynamicChangeDetector, 1); // warmup
|
||||||
|
|
||||||
|
bindAction(
|
||||||
|
'#ng2ChangeDetectionDynamicReads',
|
||||||
|
() => microBenchmark('detectChangesAvg', numberOfRuns,
|
||||||
|
() => runChangeDetectionReads(ng2DynamicChangeDetector, numberOfRuns)));
|
||||||
|
|
||||||
|
bindAction('#ng2ChangeDetectionDynamicWrites',
|
||||||
|
() => microBenchmark(
|
||||||
|
'detectChangesAvg', numberOfRuns,
|
||||||
|
() => runChangeDetectionWrites(ng2DynamicChangeDetector, numberOfRuns, object)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -- JIT
|
||||||
|
// Reenable when we have transformers for Dart
|
||||||
|
if (isJsObject({})) {
|
||||||
|
var ng2JitChangeDetector =
|
||||||
|
setUpChangeDetection(new JitChangeDetection(null), numberOfDetectors, object);
|
||||||
|
|
||||||
|
runChangeDetectionReads(ng2JitChangeDetector, 1); // warmup
|
||||||
|
|
||||||
|
bindAction(
|
||||||
|
'#ng2ChangeDetectionJitReads',
|
||||||
|
() => microBenchmark('detectChangesAvg', numberOfRuns,
|
||||||
|
() => runChangeDetectionReads(ng2JitChangeDetector, numberOfRuns)));
|
||||||
|
|
||||||
|
bindAction('#ng2ChangeDetectionJitWrites',
|
||||||
|
() => microBenchmark(
|
||||||
|
'detectChangesAvg', numberOfRuns,
|
||||||
|
() => runChangeDetectionWrites(ng2JitChangeDetector, numberOfRuns, object)));
|
||||||
|
} else {
|
||||||
|
bindAction('#ng2ChangeDetectionJitReads', () => {});
|
||||||
|
bindAction('#ng2ChangeDetectionJitWrites', () => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeDirectives {
|
||||||
|
targetObj: Obj;
|
||||||
|
|
||||||
|
constructor(targetObj) { this.targetObj = targetObj; }
|
||||||
|
|
||||||
|
getDirectiveFor(record) { return this.targetObj; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class DummyDispatcher extends ChangeDispatcher {
|
||||||
|
notifyOnBinding(bindingRecord, newValue) { throw "Should not be used"; }
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {DateWrapper, Type, print} from 'angular2/src/facade/lang';
|
import {DateWrapper, Type, print} from 'angular2/src/facade/lang';
|
||||||
import {NativeShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
|
import {
|
||||||
|
NativeShadowDomStrategy
|
||||||
|
} from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
|
||||||
|
|
||||||
import {Parser, Lexer, DynamicChangeDetection} from 'angular2/change_detection';
|
import {Parser, Lexer, DynamicChangeDetection} from 'angular2/change_detection';
|
||||||
|
|
||||||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
||||||
|
|
||||||
import {Component} from 'angular2/src/core/annotations_impl/annotations';
|
import {Component, Directive, View} from 'angular2/angular2';
|
||||||
import {Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
|
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
|
||||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||||
|
@ -37,26 +37,18 @@ export function main() {
|
||||||
var urlResolver = new UrlResolver();
|
var urlResolver = new UrlResolver();
|
||||||
var styleUrlResolver = new StyleUrlResolver(urlResolver);
|
var styleUrlResolver = new StyleUrlResolver(urlResolver);
|
||||||
var shadowDomStrategy = new NativeShadowDomStrategy(styleUrlResolver);
|
var shadowDomStrategy = new NativeShadowDomStrategy(styleUrlResolver);
|
||||||
var renderCompiler = new rc.DefaultDomCompiler(
|
var renderCompiler = new rc.DefaultDomCompiler(new Parser(new Lexer()), shadowDomStrategy,
|
||||||
new Parser(new Lexer()), shadowDomStrategy, new TemplateLoader(null, urlResolver)
|
new TemplateLoader(null, urlResolver));
|
||||||
);
|
var compiler =
|
||||||
var compiler = new Compiler(
|
new Compiler(reader, cache, templateResolver, new ComponentUrlMapper(), urlResolver,
|
||||||
reader,
|
renderCompiler, new ProtoViewFactory(new DynamicChangeDetection(null)));
|
||||||
cache,
|
|
||||||
templateResolver,
|
|
||||||
new ComponentUrlMapper(),
|
|
||||||
urlResolver,
|
|
||||||
renderCompiler,
|
|
||||||
new ProtoViewFactory(new DynamicChangeDetection(null))
|
|
||||||
);
|
|
||||||
|
|
||||||
function measureWrapper(func, desc) {
|
function measureWrapper(func, desc) {
|
||||||
return function() {
|
return function() {
|
||||||
var begin = DateWrapper.now();
|
var begin = DateWrapper.now();
|
||||||
print(`[${desc}] Begin...`);
|
print(`[${desc}] Begin...`);
|
||||||
var onSuccess = function(_) {
|
var onSuccess = function(_) {
|
||||||
var elapsedMs = DateWrapper.toMillis(
|
var elapsedMs = DateWrapper.toMillis(DateWrapper.now()) - DateWrapper.toMillis(begin);
|
||||||
DateWrapper.now()) - DateWrapper.toMillis(begin);
|
|
||||||
print(`[${desc}] ...done, took ${elapsedMs} ms`);
|
print(`[${desc}] ...done, took ${elapsedMs} ms`);
|
||||||
};
|
};
|
||||||
PromiseWrapper.then(func(), onSuccess, null);
|
PromiseWrapper.then(func(), onSuccess, null);
|
||||||
|
@ -73,65 +65,39 @@ export function main() {
|
||||||
return compiler.compile(BenchmarkComponentWithBindings);
|
return compiler.compile(BenchmarkComponentWithBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
bindAction('#compileNoBindings',
|
bindAction('#compileNoBindings', measureWrapper(compileNoBindings, 'No Bindings'));
|
||||||
measureWrapper(compileNoBindings, 'No Bindings'));
|
bindAction('#compileWithBindings', measureWrapper(compileWithBindings, 'With Bindings'));
|
||||||
bindAction('#compileWithBindings',
|
|
||||||
measureWrapper(compileWithBindings, 'With Bindings'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({
|
@Directive({selector: '[dir0]', properties: ['prop: attr0']})
|
||||||
selector: '[dir0]',
|
class Dir0 {
|
||||||
properties: [
|
}
|
||||||
'prop: attr0'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
class Dir0 {}
|
|
||||||
|
|
||||||
@Directive({
|
@Directive({selector: '[dir1]', properties: ['prop: attr1']})
|
||||||
selector: '[dir1]',
|
|
||||||
properties: [
|
|
||||||
'prop: attr1'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
class Dir1 {
|
class Dir1 {
|
||||||
constructor(dir0: Dir0) {}
|
constructor(dir0: Dir0) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({
|
@Directive({selector: '[dir2]', properties: ['prop: attr2']})
|
||||||
selector: '[dir2]',
|
|
||||||
properties: [
|
|
||||||
'prop: attr2'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
class Dir2 {
|
class Dir2 {
|
||||||
constructor(dir1: Dir1) {}
|
constructor(dir1: Dir1) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({
|
@Directive({selector: '[dir3]', properties: ['prop: attr3']})
|
||||||
selector: '[dir3]',
|
|
||||||
properties: [
|
|
||||||
'prop: attr3'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
class Dir3 {
|
class Dir3 {
|
||||||
constructor(dir2: Dir2) {}
|
constructor(dir2: Dir2) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({
|
@Directive({selector: '[dir4]', properties: ['prop: attr4']})
|
||||||
selector: '[dir4]',
|
|
||||||
properties: [
|
|
||||||
'prop: attr4'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
class Dir4 {
|
class Dir4 {
|
||||||
constructor(dir3: Dir3) {}
|
constructor(dir3: Dir3) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultipleTemplateResolver extends TemplateResolver {
|
class MultipleTemplateResolver extends TemplateResolver {
|
||||||
_multiple: num;
|
_multiple: number;
|
||||||
_cache: Map;
|
_cache: Map<any, any>;
|
||||||
|
|
||||||
constructor(multiple: num, components: List) {
|
constructor(multiple: number, components: List<Type>) {
|
||||||
super();
|
super();
|
||||||
this._multiple = multiple;
|
this._multiple = multiple;
|
||||||
this._cache = MapWrapper.create();
|
this._cache = MapWrapper.create();
|
||||||
|
@ -149,10 +115,8 @@ class MultipleTemplateResolver extends TemplateResolver {
|
||||||
|
|
||||||
resolve(component: Type): View {
|
resolve(component: Type): View {
|
||||||
var view = super.resolve(component);
|
var view = super.resolve(component);
|
||||||
var myView = new View({
|
var myView =
|
||||||
template: MapWrapper.get(this._cache, component),
|
new View({template: MapWrapper.get(this._cache, component), directives: view.directives});
|
||||||
directives: view.directives
|
|
||||||
});
|
|
||||||
return myView;
|
return myView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +136,8 @@ class MultipleTemplateResolver extends TemplateResolver {
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
})
|
})
|
||||||
class BenchmarkComponentNoBindings {}
|
class BenchmarkComponentNoBindings {
|
||||||
|
}
|
||||||
|
|
||||||
@Component()
|
@Component()
|
||||||
@View({
|
@View({
|
||||||
|
@ -194,4 +159,5 @@ class BenchmarkComponentNoBindings {}
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
})
|
})
|
||||||
class BenchmarkComponentWithBindings {}
|
class BenchmarkComponentWithBindings {
|
||||||
|
}
|
|
@ -42,9 +42,7 @@ export function main() {
|
||||||
function match() {
|
function match() {
|
||||||
var matchCount = 0;
|
var matchCount = 0;
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
fixedMatcher.match(fixedSelectors[i][0], (selector, selected) => {
|
fixedMatcher.match(fixedSelectors[i][0], (selector, selected) => { matchCount += selected; });
|
||||||
matchCount += selected;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return matchCount;
|
return matchCount;
|
||||||
}
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
import {
|
import {
|
||||||
bootstrap,
|
bootstrap,
|
||||||
|
Component,
|
||||||
|
Directive,
|
||||||
DynamicComponentLoader,
|
DynamicComponentLoader,
|
||||||
ElementRef
|
ElementRef,
|
||||||
|
View
|
||||||
} from 'angular2/angular2';
|
} from 'angular2/angular2';
|
||||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
@ -10,11 +13,6 @@ import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabil
|
||||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
||||||
import {NgIf, NgFor} from 'angular2/directives';
|
import {NgIf, NgFor} from 'angular2/directives';
|
||||||
|
|
||||||
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
|
|
||||||
// add those imports back into 'angular2/angular2';
|
|
||||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
|
|
||||||
var testList = null;
|
var testList = null;
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
|
@ -22,7 +20,8 @@ export function main() {
|
||||||
var size = getIntParameter('size');
|
var size = getIntParameter('size');
|
||||||
testList = ListWrapper.createFixedSize(size);
|
testList = ListWrapper.createFixedSize(size);
|
||||||
|
|
||||||
bootstrap(AppComponent).then((ref) => {
|
bootstrap(AppComponent)
|
||||||
|
.then((ref) => {
|
||||||
var injector = ref.injector;
|
var injector = ref.injector;
|
||||||
var app: AppComponent = injector.get(AppComponent);
|
var app: AppComponent = injector.get(AppComponent);
|
||||||
var lifeCycle = injector.get(LifeCycle);
|
var lifeCycle = injector.get(LifeCycle);
|
||||||
|
@ -75,9 +74,7 @@ class AppComponent {
|
||||||
testingWithDirectives: boolean;
|
testingWithDirectives: boolean;
|
||||||
testingDynamicComponents: boolean;
|
testingDynamicComponents: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() { this.reset(); }
|
||||||
this.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
this.list = [];
|
this.list = [];
|
||||||
|
@ -104,10 +101,12 @@ class AppComponent {
|
||||||
|
|
||||||
@Component({selector: 'dummy'})
|
@Component({selector: 'dummy'})
|
||||||
@View({template: `<div></div>`})
|
@View({template: `<div></div>`})
|
||||||
class DummyComponent {}
|
class DummyComponent {
|
||||||
|
}
|
||||||
|
|
||||||
@Directive({selector: '[dummy-decorator]'})
|
@Directive({selector: '[dummy-decorator]'})
|
||||||
class DummyDirective {}
|
class DummyDirective {
|
||||||
|
}
|
||||||
|
|
||||||
@Component({selector: 'dynamic-dummy'})
|
@Component({selector: 'dynamic-dummy'})
|
||||||
class DynamicDummy {
|
class DynamicDummy {
|
|
@ -20,19 +20,13 @@ export function main() {
|
||||||
|
|
||||||
var D_KEY = Key.get(D);
|
var D_KEY = Key.get(D);
|
||||||
var E_KEY = Key.get(E);
|
var E_KEY = Key.get(E);
|
||||||
var childInjector = injector.
|
var childInjector = injector.resolveAndCreateChild([])
|
||||||
resolveAndCreateChild([]).
|
.resolveAndCreateChild([])
|
||||||
resolveAndCreateChild([]).
|
.resolveAndCreateChild([])
|
||||||
resolveAndCreateChild([]).
|
.resolveAndCreateChild([])
|
||||||
resolveAndCreateChild([]).
|
.resolveAndCreateChild([]);
|
||||||
resolveAndCreateChild([]);
|
|
||||||
|
|
||||||
var variousBindings = [
|
var variousBindings = [A, bind(B).toClass(C), [D, [E]], bind(F).toValue(6)];
|
||||||
A,
|
|
||||||
bind(B).toClass(C),
|
|
||||||
[D, [E]],
|
|
||||||
bind(F).toValue(6)
|
|
||||||
];
|
|
||||||
|
|
||||||
var variousBindingsResolved = Injector.resolve(variousBindings);
|
var variousBindingsResolved = Injector.resolve(variousBindings);
|
||||||
|
|
||||||
|
@ -81,72 +75,43 @@ export function main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bindAction(
|
bindAction('#getByToken', () => microBenchmark('injectAvg', iterations, getByToken));
|
||||||
'#getByToken',
|
bindAction('#getByKey', () => microBenchmark('injectAvg', iterations, getByKey));
|
||||||
() => microBenchmark('injectAvg', iterations, getByToken)
|
bindAction('#getChild', () => microBenchmark('injectAvg', iterations, getChild));
|
||||||
);
|
bindAction('#instantiate', () => microBenchmark('injectAvg', iterations, instantiate));
|
||||||
bindAction(
|
bindAction('#createVariety', () => microBenchmark('injectAvg', iterations, createVariety));
|
||||||
'#getByKey',
|
bindAction('#createVarietyResolved',
|
||||||
() => microBenchmark('injectAvg', iterations, getByKey)
|
() => microBenchmark('injectAvg', iterations, createVarietyResolved));
|
||||||
);
|
|
||||||
bindAction(
|
|
||||||
'#getChild',
|
|
||||||
() => microBenchmark('injectAvg', iterations, getChild)
|
|
||||||
);
|
|
||||||
bindAction(
|
|
||||||
'#instantiate',
|
|
||||||
() => microBenchmark('injectAvg', iterations, instantiate)
|
|
||||||
);
|
|
||||||
bindAction(
|
|
||||||
'#createVariety',
|
|
||||||
() => microBenchmark('injectAvg', iterations, createVariety)
|
|
||||||
);
|
|
||||||
bindAction(
|
|
||||||
'#createVarietyResolved',
|
|
||||||
() => microBenchmark('injectAvg', iterations, createVarietyResolved)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class A {
|
class A {
|
||||||
constructor() {
|
constructor() { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class B {
|
class B {
|
||||||
constructor(a:A) {
|
constructor(a: A) { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class C {
|
class C {
|
||||||
constructor(b:B) {
|
constructor(b: B) { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class D {
|
class D {
|
||||||
constructor(c:C, b:B) {
|
constructor(c: C, b: B) { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class E {
|
class E {
|
||||||
constructor(d:D, c:C) {
|
constructor(d: D, c: C) { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class F {
|
class F {
|
||||||
constructor(e:E, d:D) {
|
constructor(e: E, d: D) { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -36,33 +36,21 @@ export function main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bindAction(
|
bindAction('#instantiate', () => microBenchmark('instantiateAvg', iterations, instantiate));
|
||||||
'#instantiate',
|
bindAction('#hydrate', () => microBenchmark('instantiateAvg', iterations, hydrate));
|
||||||
() => microBenchmark('instantiateAvg', iterations, instantiate)
|
|
||||||
);
|
|
||||||
bindAction(
|
|
||||||
'#hydrate',
|
|
||||||
() => microBenchmark('instantiateAvg', iterations, hydrate)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class A {
|
class A {
|
||||||
constructor() {
|
constructor() { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class B {
|
class B {
|
||||||
constructor() {
|
constructor() { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class C {
|
class C {
|
||||||
constructor(a:A, b:B) {
|
constructor(a: A, b: B) { count++; }
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,9 +1,4 @@
|
||||||
import {bootstrap} from 'angular2/angular2';
|
import {bootstrap, Component, Directive, View} from 'angular2/angular2';
|
||||||
|
|
||||||
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
|
|
||||||
// add those imports back into 'angular2/angular2';
|
|
||||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
|
|
||||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
|
|
||||||
|
@ -11,7 +6,11 @@ import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
|
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
import {window, document, gc} from 'angular2/src/facade/browser';
|
import {window, document, gc} from 'angular2/src/facade/browser';
|
||||||
import {getIntParameter, getStringParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
import {
|
||||||
|
getIntParameter,
|
||||||
|
getStringParameter,
|
||||||
|
bindAction
|
||||||
|
} from 'angular2/src/test_lib/benchmark_util';
|
||||||
|
|
||||||
import {NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault} from 'angular2/directives';
|
import {NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault} from 'angular2/directives';
|
||||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||||
|
@ -27,7 +26,8 @@ export const LARGETABLE_COLS = 'LargetableComponent.cols';
|
||||||
|
|
||||||
function _createBindings() {
|
function _createBindings() {
|
||||||
return [
|
return [
|
||||||
bind(BENCHMARK_TYPE).toValue(getStringParameter('benchmarkType')),
|
bind(BENCHMARK_TYPE)
|
||||||
|
.toValue(getStringParameter('benchmarkType')),
|
||||||
bind(LARGETABLE_ROWS).toValue(getIntParameter('rows')),
|
bind(LARGETABLE_ROWS).toValue(getIntParameter('rows')),
|
||||||
bind(LARGETABLE_COLS).toValue(getIntParameter('columns'))
|
bind(LARGETABLE_COLS).toValue(getIntParameter('columns'))
|
||||||
];
|
];
|
||||||
|
@ -55,8 +55,7 @@ export function main() {
|
||||||
BrowserDomAdapter.makeCurrent();
|
BrowserDomAdapter.makeCurrent();
|
||||||
var totalRows = getIntParameter('rows');
|
var totalRows = getIntParameter('rows');
|
||||||
var totalColumns = getIntParameter('columns');
|
var totalColumns = getIntParameter('columns');
|
||||||
BASELINE_LARGETABLE_TEMPLATE = DOM.createTemplate(
|
BASELINE_LARGETABLE_TEMPLATE = DOM.createTemplate('<table></table>');
|
||||||
'<table></table>');
|
|
||||||
|
|
||||||
setupReflector();
|
setupReflector();
|
||||||
|
|
||||||
|
@ -118,7 +117,8 @@ export function main() {
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
function initNg2() {
|
function initNg2() {
|
||||||
bootstrap(AppComponent, _createBindings()).then((ref) => {
|
bootstrap(AppComponent, _createBindings())
|
||||||
|
.then((ref) => {
|
||||||
var injector = ref.injector;
|
var injector = ref.injector;
|
||||||
app = injector.get(AppComponent);
|
app = injector.get(AppComponent);
|
||||||
lifecycle = injector.get(LifeCycle);
|
lifecycle = injector.get(LifeCycle);
|
||||||
|
@ -129,16 +129,13 @@ export function main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function baselineDestroyDom() {
|
function baselineDestroyDom() { baselineRootLargetableComponent.update(buildTable(0, 0)); }
|
||||||
baselineRootLargetableComponent.update(buildTable(0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
function baselineCreateDom() {
|
function baselineCreateDom() {
|
||||||
baselineRootLargetableComponent.update(buildTable(totalRows, totalColumns));
|
baselineRootLargetableComponent.update(buildTable(totalRows, totalColumns));
|
||||||
}
|
}
|
||||||
|
|
||||||
function initBaseline() {
|
function initBaseline() {
|
||||||
|
|
||||||
baselineRootLargetableComponent = new BaseLineLargetableComponent(
|
baselineRootLargetableComponent = new BaseLineLargetableComponent(
|
||||||
DOM.querySelector(document, 'baseline'), getStringParameter('benchmarkType'),
|
DOM.querySelector(document, 'baseline'), getStringParameter('benchmarkType'),
|
||||||
getIntParameter('rows'), getIntParameter('columns'));
|
getIntParameter('rows'), getIntParameter('columns'));
|
||||||
|
@ -147,7 +144,8 @@ export function main() {
|
||||||
bindAction('#baselineCreateDom', baselineCreateDom);
|
bindAction('#baselineCreateDom', baselineCreateDom);
|
||||||
|
|
||||||
bindAction('#baselineUpdateDomProfile', profile(baselineCreateDom, noop, 'baseline-update'));
|
bindAction('#baselineUpdateDomProfile', profile(baselineCreateDom, noop, 'baseline-update'));
|
||||||
bindAction('#baselineCreateDomProfile', profile(baselineCreateDom, baselineDestroyDom, 'baseline-create'));
|
bindAction('#baselineCreateDomProfile',
|
||||||
|
profile(baselineCreateDom, baselineDestroyDom, 'baseline-create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
initNg2();
|
initNg2();
|
||||||
|
@ -189,8 +187,7 @@ class BaseLineLargetableComponent {
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
this.columns = columns;
|
this.columns = columns;
|
||||||
this.table = DOM.clone(BASELINE_LARGETABLE_TEMPLATE.content.firstChild);
|
this.table = DOM.clone(BASELINE_LARGETABLE_TEMPLATE.content.firstChild);
|
||||||
var shadowRoot = DOM.createShadowRoot(this.element)
|
var shadowRoot = DOM.createShadowRoot(this.element) DOM.appendChild(shadowRoot, this.table);
|
||||||
DOM.appendChild(shadowRoot, this.table);
|
|
||||||
}
|
}
|
||||||
update(tbody) {
|
update(tbody) {
|
||||||
var oldBody = DOM.querySelector(this.table, 'tbody');
|
var oldBody = DOM.querySelector(this.table, 'tbody');
|
||||||
|
@ -210,18 +207,12 @@ class CellData {
|
||||||
this.j = j;
|
this.j = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
jFn () {
|
jFn() { return this.j; }
|
||||||
return this.j;
|
|
||||||
|
iFn() { return this.i; }
|
||||||
}
|
}
|
||||||
|
|
||||||
iFn () {
|
@Component({selector: 'app'})
|
||||||
return this.i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app'
|
|
||||||
})
|
|
||||||
@View({
|
@View({
|
||||||
directives: [LargetableComponent],
|
directives: [LargetableComponent],
|
||||||
template: `<largetable [data]='data' [benchmarkType]='benchmarkType'></largetable>`
|
template: `<largetable [data]='data' [benchmarkType]='benchmarkType'></largetable>`
|
||||||
|
@ -231,13 +222,7 @@ class AppComponent {
|
||||||
benchmarkType: string;
|
benchmarkType: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({selector: 'largetable', properties: ['data', 'benchmarkType']})
|
||||||
selector: 'largetable',
|
|
||||||
properties: [
|
|
||||||
'data',
|
|
||||||
'benchmarkType'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
@View({
|
||||||
directives: [NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault],
|
directives: [NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault],
|
||||||
template: `
|
template: `
|
||||||
|
@ -277,13 +262,10 @@ class LargetableComponent {
|
||||||
benchmarkType: string;
|
benchmarkType: string;
|
||||||
rows: number;
|
rows: number;
|
||||||
columns: number;
|
columns: number;
|
||||||
constructor(
|
constructor(@Inject(BENCHMARK_TYPE) benchmarkType: BENCHMARK_TYPE,
|
||||||
@Inject(BENCHMARK_TYPE) benchmarkType,
|
@Inject(LARGETABLE_ROWS) rows: LARGETABLE_ROWS, @Inject(LARGETABLE_COLS) columns) {
|
||||||
@Inject(LARGETABLE_ROWS) rows,
|
|
||||||
@Inject(LARGETABLE_COLS) columns) {
|
|
||||||
this.benchmarkType = benchmarkType;
|
this.benchmarkType = benchmarkType;
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
this.columns = columns;
|
this.columns = columns;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import {int, isPresent} from 'angular2/src/facade/lang';
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
||||||
import {TimerWrapper} from 'angular2/src/facade/async';
|
import {TimerWrapper} from 'angular2/src/facade/async';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {ScrollAreaComponent} from './scroll_area';
|
import {ScrollAreaComponent} from './scroll_area';
|
||||||
import {NgIf, NgFor} from 'angular2/directives';
|
import {NgIf, NgFor} from 'angular2/directives';
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
import {document} from 'angular2/src/facade/browser';
|
import {document} from 'angular2/src/facade/browser';
|
||||||
|
|
||||||
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
|
import {Component, Directive, View} from 'angular2/angular2';
|
||||||
// add those imports back into 'angular2/angular2';
|
|
||||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
|
|
||||||
@Component({selector: 'scroll-app'})
|
@Component({selector: 'scroll-app'})
|
||||||
@View({
|
@View({
|
||||||
|
@ -40,9 +38,7 @@ export class App {
|
||||||
for (var i = 0; i < appSize; i++) {
|
for (var i = 0; i < appSize; i++) {
|
||||||
ListWrapper.push(this.scrollAreas, i);
|
ListWrapper.push(this.scrollAreas, i);
|
||||||
}
|
}
|
||||||
bindAction('#run-btn', () => {
|
bindAction('#run-btn', () => { this.runBenchmark(); });
|
||||||
this.runBenchmark();
|
|
||||||
});
|
|
||||||
bindAction('#reset-btn', () => {
|
bindAction('#reset-btn', () => {
|
||||||
this._getScrollDiv().scrollTop = 0;
|
this._getScrollDiv().scrollTop = 0;
|
||||||
var existingMarker = this._locateFinishedMarker();
|
var existingMarker = this._locateFinishedMarker();
|
||||||
|
@ -66,7 +62,7 @@ export class App {
|
||||||
this._scheduleFinishedMarker();
|
this._scheduleFinishedMarker();
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
};
|
||||||
scheduleScroll();
|
scheduleScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,11 +81,7 @@ export class App {
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_locateFinishedMarker() {
|
_locateFinishedMarker() { return DOM.querySelector(document.body, '#done'); }
|
||||||
return DOM.querySelector(document.body, '#done');
|
|
||||||
}
|
|
||||||
|
|
||||||
_getScrollDiv() {
|
_getScrollDiv() { return DOM.query('body /deep/ #testArea /deep/ #scrollDiv'); }
|
||||||
return DOM.query('body /deep/ #testArea /deep/ #scrollDiv');
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,175 +0,0 @@
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
|
||||||
import {Company, Opportunity, Offering, Account, CustomDate, STATUS_LIST}
|
|
||||||
from './common';
|
|
||||||
import {NgFor} from 'angular2/directives';
|
|
||||||
|
|
||||||
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
|
|
||||||
// add those imports back into 'angular2/angular2';
|
|
||||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
|
|
||||||
export class HasStyle {
|
|
||||||
style:Map;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.style = MapWrapper.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
set width(w) {
|
|
||||||
MapWrapper.set(this.style, 'width', w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'company-name',
|
|
||||||
properties: [
|
|
||||||
'width: cell-width',
|
|
||||||
'company'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
|
||||||
directives: [],
|
|
||||||
template: `<div [style]="style">{{company.name}}</div>`
|
|
||||||
})
|
|
||||||
export class CompanyNameComponent extends HasStyle {
|
|
||||||
company:Company;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'opportunity-name',
|
|
||||||
properties: [
|
|
||||||
'width: cell-width',
|
|
||||||
'opportunity'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
|
||||||
directives: [],
|
|
||||||
template: `<div [style]="style">{{opportunity.name}}</div>`
|
|
||||||
})
|
|
||||||
export class OpportunityNameComponent extends HasStyle {
|
|
||||||
opportunity:Opportunity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'offering-name',
|
|
||||||
properties: [
|
|
||||||
'width: cell-width',
|
|
||||||
'offering'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
|
||||||
directives: [],
|
|
||||||
template: `<div [style]="style">{{offering.name}}</div>`
|
|
||||||
})
|
|
||||||
export class OfferingNameComponent extends HasStyle {
|
|
||||||
offering:Offering;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Stage {
|
|
||||||
name:string;
|
|
||||||
isDisabled:boolean;
|
|
||||||
style:Map;
|
|
||||||
apply:Function;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'stage-buttons',
|
|
||||||
properties: [
|
|
||||||
'width: cell-width',
|
|
||||||
'offering'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
|
||||||
directives: [NgFor],
|
|
||||||
template: `
|
|
||||||
<div [style]="style">
|
|
||||||
<button template="ng-for #stage of stages"
|
|
||||||
[disabled]="stage.isDisabled"
|
|
||||||
[style]="stage.style"
|
|
||||||
on-click="setStage(stage)">
|
|
||||||
{{stage.name}}
|
|
||||||
</button>
|
|
||||||
</div>`
|
|
||||||
})
|
|
||||||
export class StageButtonsComponent extends HasStyle {
|
|
||||||
_offering:Offering;
|
|
||||||
stages:List<Stage>;
|
|
||||||
|
|
||||||
get offering():Offering { return this._offering; }
|
|
||||||
|
|
||||||
set offering(offering:Offering) {
|
|
||||||
this._offering = offering;
|
|
||||||
this._computeStageButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
setStage(stage:Stage) {
|
|
||||||
this._offering.status = stage.name;
|
|
||||||
this._computeStageButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeStageButtons() {
|
|
||||||
var disabled = true;
|
|
||||||
this.stages = ListWrapper.clone(STATUS_LIST
|
|
||||||
.map((status) => {
|
|
||||||
var isCurrent = this._offering.status == status;
|
|
||||||
var stage = new Stage();
|
|
||||||
stage.name = status;
|
|
||||||
stage.isDisabled = disabled;
|
|
||||||
var stageStyle = MapWrapper.create();
|
|
||||||
MapWrapper.set(stageStyle, 'background-color',
|
|
||||||
disabled
|
|
||||||
? '#DDD'
|
|
||||||
: isCurrent
|
|
||||||
? '#DDF'
|
|
||||||
: '#FDD');
|
|
||||||
stage.style = stageStyle;
|
|
||||||
if (isCurrent) {
|
|
||||||
disabled = false;
|
|
||||||
}
|
|
||||||
return stage;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'account-cell',
|
|
||||||
properties: [
|
|
||||||
'width: cell-width',
|
|
||||||
'account'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
|
||||||
directives: [],
|
|
||||||
template: `
|
|
||||||
<div [style]="style">
|
|
||||||
<a href="/account/{{account.accountId}}">
|
|
||||||
{{account.accountId}}
|
|
||||||
</a>
|
|
||||||
</div>`
|
|
||||||
})
|
|
||||||
export class AccountCellComponent extends HasStyle {
|
|
||||||
account:Account;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'formatted-cell',
|
|
||||||
properties: [
|
|
||||||
'width: cell-width',
|
|
||||||
'value'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
|
||||||
directives: [],
|
|
||||||
template: `<div [style]="style">{{formattedValue}}</div>`
|
|
||||||
})
|
|
||||||
export class FormattedCellComponent extends HasStyle {
|
|
||||||
formattedValue:string;
|
|
||||||
|
|
||||||
set value(value) {
|
|
||||||
if (value instanceof CustomDate) {
|
|
||||||
this.formattedValue = `${value.month}/${value.day}/${value.year}`;
|
|
||||||
} else {
|
|
||||||
this.formattedValue = value.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
import {Company, Opportunity, Offering, Account, CustomDate, STATUS_LIST} from './common';
|
||||||
|
import {NgFor} from 'angular2/directives';
|
||||||
|
|
||||||
|
import {Component, Directive, View} from 'angular2/angular2';
|
||||||
|
|
||||||
|
export class HasStyle {
|
||||||
|
style: Map<any, any>;
|
||||||
|
|
||||||
|
constructor() { this.style = MapWrapper.create(); }
|
||||||
|
|
||||||
|
set width(w) { MapWrapper.set(this.style, 'width', w); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'company-name', properties: ['width: cell-width', 'company']})
|
||||||
|
@View({directives: [], template: `<div [style]="style">{{company.name}}</div>`})
|
||||||
|
export class CompanyNameComponent extends HasStyle {
|
||||||
|
company: Company;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'opportunity-name', properties: ['width: cell-width', 'opportunity']})
|
||||||
|
@View({directives: [], template: `<div [style]="style">{{opportunity.name}}</div>`})
|
||||||
|
export class OpportunityNameComponent extends HasStyle {
|
||||||
|
opportunity: Opportunity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'offering-name', properties: ['width: cell-width', 'offering']})
|
||||||
|
@View({directives: [], template: `<div [style]="style">{{offering.name}}</div>`})
|
||||||
|
export class OfferingNameComponent extends HasStyle {
|
||||||
|
offering: Offering;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Stage {
|
||||||
|
name: string;
|
||||||
|
isDisabled: boolean;
|
||||||
|
style: Map;
|
||||||
|
apply: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'stage-buttons', properties: ['width: cell-width', 'offering']})
|
||||||
|
@View({
|
||||||
|
directives: [NgFor],
|
||||||
|
template: `
|
||||||
|
<div [style]="style">
|
||||||
|
<button template="ng-for #stage of stages"
|
||||||
|
[disabled]="stage.isDisabled"
|
||||||
|
[style]="stage.style"
|
||||||
|
on-click="setStage(stage)">
|
||||||
|
{{stage.name}}
|
||||||
|
</button>
|
||||||
|
</div>`
|
||||||
|
})
|
||||||
|
export class StageButtonsComponent extends HasStyle {
|
||||||
|
_offering: Offering;
|
||||||
|
stages: List<Stage>;
|
||||||
|
|
||||||
|
get offering(): Offering { return this._offering; }
|
||||||
|
|
||||||
|
set offering(offering: Offering) {
|
||||||
|
this._offering = offering;
|
||||||
|
this._computeStageButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
setStage(stage: Stage) {
|
||||||
|
this._offering.status = stage.name;
|
||||||
|
this._computeStageButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStageButtons() {
|
||||||
|
var disabled = true;
|
||||||
|
this.stages = ListWrapper.clone(STATUS_LIST.map((status) => {
|
||||||
|
var isCurrent = this._offering.status == status;
|
||||||
|
var stage = new Stage();
|
||||||
|
stage.name = status;
|
||||||
|
stage.isDisabled = disabled;
|
||||||
|
var stageStyle = MapWrapper.create();
|
||||||
|
MapWrapper.set(stageStyle, 'background-color',
|
||||||
|
disabled ? '#DDD' : isCurrent ? '#DDF' : '#FDD');
|
||||||
|
stage.style = stageStyle;
|
||||||
|
if (isCurrent) {
|
||||||
|
disabled = false;
|
||||||
|
}
|
||||||
|
return stage;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'account-cell', properties: ['width: cell-width', 'account']})
|
||||||
|
@View({
|
||||||
|
directives: [],
|
||||||
|
template: `
|
||||||
|
<div [style]="style">
|
||||||
|
<a href="/account/{{account.accountId}}">
|
||||||
|
{{account.accountId}}
|
||||||
|
</a>
|
||||||
|
</div>`
|
||||||
|
})
|
||||||
|
export class AccountCellComponent extends HasStyle {
|
||||||
|
account: Account;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'formatted-cell', properties: ['width: cell-width', 'value']})
|
||||||
|
@View({directives: [], template: `<div [style]="style">{{formattedValue}}</div>`})
|
||||||
|
export class FormattedCellComponent extends HasStyle {
|
||||||
|
formattedValue: string;
|
||||||
|
|
||||||
|
set value(value) {
|
||||||
|
if (value instanceof CustomDate) {
|
||||||
|
this.formattedValue = `${value.month}/${value.day}/${value.year}`;
|
||||||
|
} else {
|
||||||
|
this.formattedValue = value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,203 +0,0 @@
|
||||||
import {Math} from 'angular2/src/facade/math';
|
|
||||||
|
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
|
||||||
|
|
||||||
export var ITEMS = 1000;
|
|
||||||
export var ITEM_HEIGHT = 40;
|
|
||||||
export var VISIBLE_ITEMS = 17;
|
|
||||||
|
|
||||||
export var HEIGHT = ITEMS * ITEM_HEIGHT;
|
|
||||||
export var VIEW_PORT_HEIGHT = ITEM_HEIGHT * VISIBLE_ITEMS;
|
|
||||||
|
|
||||||
export var COMPANY_NAME_WIDTH = 100;
|
|
||||||
export var OPPORTUNITY_NAME_WIDTH = 100;
|
|
||||||
export var OFFERING_NAME_WIDTH = 100;
|
|
||||||
export var ACCOUNT_CELL_WIDTH = 50;
|
|
||||||
export var BASE_POINTS_WIDTH = 50;
|
|
||||||
export var KICKER_POINTS_WIDTH = 50;
|
|
||||||
export var STAGE_BUTTONS_WIDTH = 220;
|
|
||||||
export var BUNDLES_WIDTH = 120;
|
|
||||||
export var DUE_DATE_WIDTH = 100;
|
|
||||||
export var END_DATE_WIDTH = 100;
|
|
||||||
export var AAT_STATUS_WIDTH = 100;
|
|
||||||
export var ROW_WIDTH = COMPANY_NAME_WIDTH +
|
|
||||||
OPPORTUNITY_NAME_WIDTH +
|
|
||||||
OFFERING_NAME_WIDTH +
|
|
||||||
ACCOUNT_CELL_WIDTH +
|
|
||||||
BASE_POINTS_WIDTH +
|
|
||||||
KICKER_POINTS_WIDTH +
|
|
||||||
STAGE_BUTTONS_WIDTH +
|
|
||||||
BUNDLES_WIDTH +
|
|
||||||
DUE_DATE_WIDTH +
|
|
||||||
END_DATE_WIDTH +
|
|
||||||
AAT_STATUS_WIDTH;
|
|
||||||
|
|
||||||
export var STATUS_LIST = [
|
|
||||||
'Planned', 'Pitched', 'Won', 'Lost'
|
|
||||||
];
|
|
||||||
|
|
||||||
export var AAT_STATUS_LIST = [
|
|
||||||
'Active', 'Passive', 'Abandoned'
|
|
||||||
];
|
|
||||||
|
|
||||||
// Imitate Streamy entities.
|
|
||||||
|
|
||||||
// Just a non-trivial object. Nothing fancy or correct.
|
|
||||||
export class CustomDate {
|
|
||||||
year:number;
|
|
||||||
month:number;
|
|
||||||
day:number;
|
|
||||||
|
|
||||||
constructor(y:number, m:number, d:number) {
|
|
||||||
this.year = y;
|
|
||||||
this.month = m;
|
|
||||||
this.day = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
addDays(days:number):CustomDate {
|
|
||||||
var newDay = this.day + days;
|
|
||||||
var newMonth = this.month + Math.floor(newDay / 30);
|
|
||||||
newDay = newDay % 30;
|
|
||||||
var newYear = this.year + Math.floor(newMonth / 12);
|
|
||||||
return new CustomDate(newYear, newMonth, newDay);
|
|
||||||
}
|
|
||||||
|
|
||||||
static now():CustomDate {
|
|
||||||
return new CustomDate(2014, 1, 28);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class RawEntity {
|
|
||||||
|
|
||||||
_data:Map;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._data = MapWrapper.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
get(key:string) {
|
|
||||||
if (key.indexOf('.') == -1) {
|
|
||||||
return this._data[key];
|
|
||||||
}
|
|
||||||
var pieces = key.split('.');
|
|
||||||
var last = ListWrapper.last(pieces);
|
|
||||||
pieces.length = pieces.length - 1;
|
|
||||||
var target = _resolve(pieces, this);
|
|
||||||
if (target == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return target[last];
|
|
||||||
}
|
|
||||||
|
|
||||||
set(key:string, value) {
|
|
||||||
if (key.indexOf('.') == -1) {
|
|
||||||
this._data[key] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pieces = key.split('.');
|
|
||||||
var last = ListWrapper.last(pieces);
|
|
||||||
pieces.length = pieces.length - 1;
|
|
||||||
var target = _resolve(pieces, this);
|
|
||||||
target[last] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(key:string) {
|
|
||||||
if (!key.contains('.')) {
|
|
||||||
return MapWrapper.delete(this._data, key);
|
|
||||||
}
|
|
||||||
var pieces = key.split('.');
|
|
||||||
var last = ListWrapper.last(pieces);
|
|
||||||
pieces.length = pieces.length - 1;
|
|
||||||
var target = _resolve(pieces, this);
|
|
||||||
return target.remove(last);
|
|
||||||
}
|
|
||||||
|
|
||||||
_resolve(pieces, start) {
|
|
||||||
var cur = start;
|
|
||||||
for (var i = 0; i < pieces.length; i++) {
|
|
||||||
cur = cur[pieces[i]];
|
|
||||||
if (cur == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Company extends RawEntity {
|
|
||||||
get name():string { return this.get('name'); }
|
|
||||||
set name(val:string) {
|
|
||||||
this.set('name', val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Offering extends RawEntity {
|
|
||||||
get name():string { return this.get('name'); }
|
|
||||||
set name(val:string) {
|
|
||||||
this.set('name', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get company():Company { return this.get('company'); }
|
|
||||||
set company(val:Company) {
|
|
||||||
this.set('company', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get opportunity():Opportunity { return this.get('opportunity'); }
|
|
||||||
set opportunity(val:Opportunity) {
|
|
||||||
this.set('opportunity', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get account():Account { return this.get('account'); }
|
|
||||||
set account(val:Account) {
|
|
||||||
this.set('account', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get basePoints():number { return this.get('basePoints'); }
|
|
||||||
set basePoints(val:number) {
|
|
||||||
this.set('basePoints', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get kickerPoints():number { return this.get('kickerPoints'); }
|
|
||||||
set kickerPoints(val:number) {
|
|
||||||
this.set('kickerPoints', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get status():string { return this.get('status'); }
|
|
||||||
set status(val:string) {
|
|
||||||
this.set('status', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get bundles():string { return this.get('bundles'); }
|
|
||||||
set bundles(val:string) {
|
|
||||||
this.set('bundles', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get dueDate():CustomDate { return this.get('dueDate'); }
|
|
||||||
set dueDate(val:CustomDate) {
|
|
||||||
this.set('dueDate', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get endDate():CustomDate { return this.get('endDate'); }
|
|
||||||
set endDate(val:CustomDate) {
|
|
||||||
this.set('endDate', val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get aatStatus():string { return this.get('aatStatus'); }
|
|
||||||
set aatStatus(val:string) {
|
|
||||||
this.set('aatStatus', val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Opportunity extends RawEntity {
|
|
||||||
get name():string { return this.get('name'); }
|
|
||||||
set name(val:string) {
|
|
||||||
this.set('name', val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Account extends RawEntity {
|
|
||||||
get accountId():number { return this.get('accountId'); }
|
|
||||||
set accountId(val:number) {
|
|
||||||
this.set('accountId', val);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
import {Math} from 'angular2/src/facade/math';
|
||||||
|
|
||||||
|
import {ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
|
export var ITEMS = 1000;
|
||||||
|
export var ITEM_HEIGHT = 40;
|
||||||
|
export var VISIBLE_ITEMS = 17;
|
||||||
|
|
||||||
|
export var HEIGHT = ITEMS * ITEM_HEIGHT;
|
||||||
|
export var VIEW_PORT_HEIGHT = ITEM_HEIGHT * VISIBLE_ITEMS;
|
||||||
|
|
||||||
|
export var COMPANY_NAME_WIDTH = 100;
|
||||||
|
export var OPPORTUNITY_NAME_WIDTH = 100;
|
||||||
|
export var OFFERING_NAME_WIDTH = 100;
|
||||||
|
export var ACCOUNT_CELL_WIDTH = 50;
|
||||||
|
export var BASE_POINTS_WIDTH = 50;
|
||||||
|
export var KICKER_POINTS_WIDTH = 50;
|
||||||
|
export var STAGE_BUTTONS_WIDTH = 220;
|
||||||
|
export var BUNDLES_WIDTH = 120;
|
||||||
|
export var DUE_DATE_WIDTH = 100;
|
||||||
|
export var END_DATE_WIDTH = 100;
|
||||||
|
export var AAT_STATUS_WIDTH = 100;
|
||||||
|
export var ROW_WIDTH = COMPANY_NAME_WIDTH + OPPORTUNITY_NAME_WIDTH + OFFERING_NAME_WIDTH +
|
||||||
|
ACCOUNT_CELL_WIDTH + BASE_POINTS_WIDTH + KICKER_POINTS_WIDTH +
|
||||||
|
STAGE_BUTTONS_WIDTH + BUNDLES_WIDTH + DUE_DATE_WIDTH + END_DATE_WIDTH +
|
||||||
|
AAT_STATUS_WIDTH;
|
||||||
|
|
||||||
|
export var STATUS_LIST = ['Planned', 'Pitched', 'Won', 'Lost'];
|
||||||
|
|
||||||
|
export var AAT_STATUS_LIST = ['Active', 'Passive', 'Abandoned'];
|
||||||
|
|
||||||
|
// Imitate Streamy entities.
|
||||||
|
|
||||||
|
// Just a non-trivial object. Nothing fancy or correct.
|
||||||
|
export class CustomDate {
|
||||||
|
year: number;
|
||||||
|
month: number;
|
||||||
|
day: number;
|
||||||
|
|
||||||
|
constructor(y: number, m: number, d: number) {
|
||||||
|
this.year = y;
|
||||||
|
this.month = m;
|
||||||
|
this.day = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
addDays(days: number): CustomDate {
|
||||||
|
var newDay = this.day + days;
|
||||||
|
var newMonth = this.month + Math.floor(newDay / 30);
|
||||||
|
newDay = newDay % 30;
|
||||||
|
var newYear = this.year + Math.floor(newMonth / 12);
|
||||||
|
return new CustomDate(newYear, newMonth, newDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static now(): CustomDate { return new CustomDate(2014, 1, 28); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RawEntity {
|
||||||
|
_data: Map<any, any>;
|
||||||
|
|
||||||
|
constructor() { this._data = MapWrapper.create(); }
|
||||||
|
|
||||||
|
get(key: string) {
|
||||||
|
if (key.indexOf('.') == -1) {
|
||||||
|
return this._data[key];
|
||||||
|
}
|
||||||
|
var pieces = key.split('.');
|
||||||
|
var last = ListWrapper.last(pieces);
|
||||||
|
pieces.length = pieces.length - 1;
|
||||||
|
var target = _resolve(pieces, this);
|
||||||
|
if (target == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return target[last];
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key: string, value) {
|
||||||
|
if (key.indexOf('.') == -1) {
|
||||||
|
this._data[key] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var pieces = key.split('.');
|
||||||
|
var last = ListWrapper.last(pieces);
|
||||||
|
pieces.length = pieces.length - 1;
|
||||||
|
var target = _resolve(pieces, this);
|
||||||
|
target[last] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(key: string) {
|
||||||
|
if (!key.contains('.')) {
|
||||||
|
return MapWrapper.delete(this._data, key);
|
||||||
|
}
|
||||||
|
var pieces = key.split('.');
|
||||||
|
var last = ListWrapper.last(pieces);
|
||||||
|
pieces.length = pieces.length - 1;
|
||||||
|
var target = _resolve(pieces, this);
|
||||||
|
return target.remove(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
_resolve(pieces, start) {
|
||||||
|
var cur = start;
|
||||||
|
for (var i = 0; i < pieces.length; i++) {
|
||||||
|
cur = cur[pieces[i]];
|
||||||
|
if (cur == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Company extends RawEntity {
|
||||||
|
get name(): string { return this.get('name'); }
|
||||||
|
set name(val: string) { this.set('name', val); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Offering extends RawEntity {
|
||||||
|
get name(): string { return this.get('name'); }
|
||||||
|
set name(val: string) { this.set('name', val); }
|
||||||
|
|
||||||
|
get company(): Company { return this.get('company'); }
|
||||||
|
set company(val: Company) { this.set('company', val); }
|
||||||
|
|
||||||
|
get opportunity(): Opportunity { return this.get('opportunity'); }
|
||||||
|
set opportunity(val: Opportunity) { this.set('opportunity', val); }
|
||||||
|
|
||||||
|
get account(): Account { return this.get('account'); }
|
||||||
|
set account(val: Account) { this.set('account', val); }
|
||||||
|
|
||||||
|
get basePoints(): number { return this.get('basePoints'); }
|
||||||
|
set basePoints(val: number) { this.set('basePoints', val); }
|
||||||
|
|
||||||
|
get kickerPoints(): number { return this.get('kickerPoints'); }
|
||||||
|
set kickerPoints(val: number) { this.set('kickerPoints', val); }
|
||||||
|
|
||||||
|
get status(): string { return this.get('status'); }
|
||||||
|
set status(val: string) { this.set('status', val); }
|
||||||
|
|
||||||
|
get bundles(): string { return this.get('bundles'); }
|
||||||
|
set bundles(val: string) { this.set('bundles', val); }
|
||||||
|
|
||||||
|
get dueDate(): CustomDate { return this.get('dueDate'); }
|
||||||
|
set dueDate(val: CustomDate) { this.set('dueDate', val); }
|
||||||
|
|
||||||
|
get endDate(): CustomDate { return this.get('endDate'); }
|
||||||
|
set endDate(val: CustomDate) { this.set('endDate', val); }
|
||||||
|
|
||||||
|
get aatStatus(): string { return this.get('aatStatus'); }
|
||||||
|
set aatStatus(val: string) { this.set('aatStatus', val); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Opportunity extends RawEntity {
|
||||||
|
get name(): string { return this.get('name'); }
|
||||||
|
set name(val: string) { this.set('name', val); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Account extends RawEntity {
|
||||||
|
get accountId(): number { return this.get('accountId'); }
|
||||||
|
set accountId(val: number) { this.set('accountId', val); }
|
||||||
|
}
|
|
@ -23,16 +23,16 @@ export function setupReflector() {
|
||||||
|
|
||||||
// TODO(kegluneq): Generate this.
|
// TODO(kegluneq): Generate this.
|
||||||
reflector.registerSetters({
|
reflector.registerSetters({
|
||||||
'style': (o, m) => {
|
'style': (o, m) =>
|
||||||
|
{
|
||||||
// HACK
|
// HACK
|
||||||
MapWrapper.forEach(m, function(v, k) {
|
MapWrapper.forEach(m, function(v, k) { o.style.setProperty(k, v); });
|
||||||
o.style.setProperty(k, v);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reflector.registerMethods({
|
reflector.registerMethods({
|
||||||
'onScroll': (o, args) => {
|
'onScroll': (o, args) =>
|
||||||
|
{
|
||||||
// HACK
|
// HACK
|
||||||
o.onScroll(args[0]);
|
o.onScroll(args[0]);
|
||||||
},
|
},
|
|
@ -1,7 +1,14 @@
|
||||||
import {int, StringWrapper} from 'angular2/src/facade/lang';
|
import {StringWrapper} from 'angular2/src/facade/lang';
|
||||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {CustomDate, Offering, Company, Opportunity, Account, STATUS_LIST,
|
import {
|
||||||
AAT_STATUS_LIST} from './common';
|
CustomDate,
|
||||||
|
Offering,
|
||||||
|
Company,
|
||||||
|
Opportunity,
|
||||||
|
Account,
|
||||||
|
STATUS_LIST,
|
||||||
|
AAT_STATUS_LIST
|
||||||
|
} from './common';
|
||||||
|
|
||||||
export function generateOfferings(count: int): List<Offering> {
|
export function generateOfferings(count: int): List<Offering> {
|
||||||
var res = [];
|
var res = [];
|
||||||
|
@ -46,8 +53,19 @@ export function generateAccount(seed:int):Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
var names = [
|
var names = [
|
||||||
'Foo', 'Bar', 'Baz', 'Qux', 'Quux', 'Garply', 'Waldo', 'Fred', 'Plugh',
|
'Foo',
|
||||||
'Xyzzy', 'Thud', 'Cruft', 'Stuff'
|
'Bar',
|
||||||
|
'Baz',
|
||||||
|
'Qux',
|
||||||
|
'Quux',
|
||||||
|
'Garply',
|
||||||
|
'Waldo',
|
||||||
|
'Fred',
|
||||||
|
'Plugh',
|
||||||
|
'Xyzzy',
|
||||||
|
'Thud',
|
||||||
|
'Cruft',
|
||||||
|
'Stuff'
|
||||||
];
|
];
|
||||||
|
|
||||||
function generateName(seed: int): string {
|
function generateName(seed: int): string {
|
|
@ -1,13 +1,17 @@
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {Math} from 'angular2/src/facade/math';
|
import {Math} from 'angular2/src/facade/math';
|
||||||
|
|
||||||
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
|
import {Component, Directive, View} from 'angular2/angular2';
|
||||||
// add those imports back into 'angular2/angular2';
|
|
||||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
|
|
||||||
import {Offering, ITEMS, ITEM_HEIGHT, VISIBLE_ITEMS, VIEW_PORT_HEIGHT,
|
import {
|
||||||
ROW_WIDTH, HEIGHT} from './common';
|
Offering,
|
||||||
|
ITEMS,
|
||||||
|
ITEM_HEIGHT,
|
||||||
|
VISIBLE_ITEMS,
|
||||||
|
VIEW_PORT_HEIGHT,
|
||||||
|
ROW_WIDTH,
|
||||||
|
HEIGHT
|
||||||
|
} from './common';
|
||||||
import {generateOfferings} from './random_data';
|
import {generateOfferings} from './random_data';
|
||||||
import {ScrollItemComponent} from './scroll_item';
|
import {ScrollItemComponent} from './scroll_item';
|
||||||
import {NgFor} from 'angular2/directives';
|
import {NgFor} from 'angular2/directives';
|
|
@ -1,24 +1,32 @@
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {CompanyNameComponent, OpportunityNameComponent,
|
import {
|
||||||
OfferingNameComponent, StageButtonsComponent, AccountCellComponent,
|
CompanyNameComponent,
|
||||||
FormattedCellComponent} from './cells';
|
OpportunityNameComponent,
|
||||||
|
OfferingNameComponent,
|
||||||
|
StageButtonsComponent,
|
||||||
|
AccountCellComponent,
|
||||||
|
FormattedCellComponent
|
||||||
|
} from './cells';
|
||||||
|
|
||||||
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
|
import {Component, Directive, View} from 'angular2/angular2';
|
||||||
// add those imports back into 'angular2/angular2';
|
|
||||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
|
|
||||||
import {Offering, ITEM_HEIGHT, COMPANY_NAME_WIDTH, OPPORTUNITY_NAME_WIDTH,
|
import {
|
||||||
OFFERING_NAME_WIDTH, ACCOUNT_CELL_WIDTH, BASE_POINTS_WIDTH,
|
Offering,
|
||||||
KICKER_POINTS_WIDTH, STAGE_BUTTONS_WIDTH, BUNDLES_WIDTH, DUE_DATE_WIDTH,
|
ITEM_HEIGHT,
|
||||||
END_DATE_WIDTH, AAT_STATUS_WIDTH} from './common';
|
COMPANY_NAME_WIDTH,
|
||||||
|
OPPORTUNITY_NAME_WIDTH,
|
||||||
|
OFFERING_NAME_WIDTH,
|
||||||
|
ACCOUNT_CELL_WIDTH,
|
||||||
|
BASE_POINTS_WIDTH,
|
||||||
|
KICKER_POINTS_WIDTH,
|
||||||
|
STAGE_BUTTONS_WIDTH,
|
||||||
|
BUNDLES_WIDTH,
|
||||||
|
DUE_DATE_WIDTH,
|
||||||
|
END_DATE_WIDTH,
|
||||||
|
AAT_STATUS_WIDTH
|
||||||
|
} from './common';
|
||||||
|
|
||||||
@Component({
|
@Component({selector: 'scroll-item', properties: ['offering']})
|
||||||
selector: 'scroll-item',
|
|
||||||
properties: [
|
|
||||||
'offering'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
@View({
|
@View({
|
||||||
directives: [
|
directives: [
|
||||||
CompanyNameComponent,
|
CompanyNameComponent,
|
||||||
|
@ -66,7 +74,6 @@ import {Offering, ITEM_HEIGHT, COMPANY_NAME_WIDTH, OPPORTUNITY_NAME_WIDTH,
|
||||||
</div>`
|
</div>`
|
||||||
})
|
})
|
||||||
export class ScrollItemComponent {
|
export class ScrollItemComponent {
|
||||||
|
|
||||||
offering: Offering;
|
offering: Offering;
|
||||||
itemStyle;
|
itemStyle;
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
import {bootstrap, ViewContainerRef, Compiler} from 'angular2/angular2';
|
import {bootstrap, Compiler, Component, Directive, View, ViewContainerRef} from 'angular2/angular2';
|
||||||
|
|
||||||
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
|
|
||||||
// add those imports back into 'angular2/angular2';
|
|
||||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
|
||||||
|
|
||||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
|
@ -12,7 +7,11 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
import {isPresent} from 'angular2/src/facade/lang';
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
import {List} from 'angular2/src/facade/collection';
|
import {List} from 'angular2/src/facade/collection';
|
||||||
import {window, document, gc} from 'angular2/src/facade/browser';
|
import {window, document, gc} from 'angular2/src/facade/browser';
|
||||||
import {getIntParameter, getStringParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
import {
|
||||||
|
getIntParameter,
|
||||||
|
getStringParameter,
|
||||||
|
bindAction
|
||||||
|
} from 'angular2/src/test_lib/benchmark_util';
|
||||||
import {NgIf} from 'angular2/directives';
|
import {NgIf} from 'angular2/directives';
|
||||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||||
import {APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_pool';
|
import {APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_pool';
|
||||||
|
@ -20,9 +19,7 @@ import {bind} from 'angular2/di';
|
||||||
|
|
||||||
function createBindings(): List {
|
function createBindings(): List {
|
||||||
var viewCacheCapacity = getStringParameter('viewcache') == 'true' ? 10000 : 1;
|
var viewCacheCapacity = getStringParameter('viewcache') == 'true' ? 10000 : 1;
|
||||||
return [
|
return [bind(APP_VIEW_POOL_CAPACITY).toValue(viewCacheCapacity)];
|
||||||
bind(APP_VIEW_POOL_CAPACITY).toValue(viewCacheCapacity)
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupReflector() {
|
function setupReflector() {
|
||||||
|
@ -40,8 +37,7 @@ export function main() {
|
||||||
|
|
||||||
BASELINE_TREE_TEMPLATE = DOM.createTemplate(
|
BASELINE_TREE_TEMPLATE = DOM.createTemplate(
|
||||||
'<span>_<template class="ng-binding"></template><template class="ng-binding"></template></span>');
|
'<span>_<template class="ng-binding"></template><template class="ng-binding"></template></span>');
|
||||||
BASELINE_IF_TEMPLATE = DOM.createTemplate(
|
BASELINE_IF_TEMPLATE = DOM.createTemplate('<span template="if"><tree></tree></span>');
|
||||||
'<span template="if"><tree></tree></span>');
|
|
||||||
|
|
||||||
var app;
|
var app;
|
||||||
var lifeCycle;
|
var lifeCycle;
|
||||||
|
@ -85,8 +81,7 @@ export function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ng2CreateDom() {
|
function ng2CreateDom() {
|
||||||
var values = count++ % 2 == 0 ?
|
var values = count++ % 2 == 0 ? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
||||||
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
|
||||||
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
||||||
|
|
||||||
app.initData = buildTree(maxDepth, values, 0);
|
app.initData = buildTree(maxDepth, values, 0);
|
||||||
|
@ -96,7 +91,8 @@ export function main() {
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
function initNg2() {
|
function initNg2() {
|
||||||
bootstrap(AppComponent, createBindings()).then((ref) => {
|
bootstrap(AppComponent, createBindings())
|
||||||
|
.then((ref) => {
|
||||||
var injector = ref.injector;
|
var injector = ref.injector;
|
||||||
lifeCycle = injector.get(LifeCycle);
|
lifeCycle = injector.get(LifeCycle);
|
||||||
|
|
||||||
|
@ -108,13 +104,10 @@ export function main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function baselineDestroyDom() {
|
function baselineDestroyDom() { baselineRootTreeComponent.update(new TreeNode('', null, null)); }
|
||||||
baselineRootTreeComponent.update(new TreeNode('', null, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
function baselineCreateDom() {
|
function baselineCreateDom() {
|
||||||
var values = count++ % 2 == 0 ?
|
var values = count++ % 2 == 0 ? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
||||||
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
|
||||||
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
||||||
|
|
||||||
baselineRootTreeComponent.update(buildTree(maxDepth, values, 0));
|
baselineRootTreeComponent.update(buildTree(maxDepth, values, 0));
|
||||||
|
@ -129,7 +122,8 @@ export function main() {
|
||||||
bindAction('#baselineCreateDom', baselineCreateDom);
|
bindAction('#baselineCreateDom', baselineCreateDom);
|
||||||
|
|
||||||
bindAction('#baselineUpdateDomProfile', profile(baselineCreateDom, noop, 'baseline-update'));
|
bindAction('#baselineUpdateDomProfile', profile(baselineCreateDom, noop, 'baseline-update'));
|
||||||
bindAction('#baselineCreateDomProfile', profile(baselineCreateDom, baselineDestroyDom, 'baseline-create'));
|
bindAction('#baselineCreateDomProfile',
|
||||||
|
profile(baselineCreateDom, baselineDestroyDom, 'baseline-create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
initNg2();
|
initNg2();
|
||||||
|
@ -149,9 +143,7 @@ class TreeNode {
|
||||||
|
|
||||||
function buildTree(maxDepth, values, curDepth) {
|
function buildTree(maxDepth, values, curDepth) {
|
||||||
if (maxDepth === curDepth) return new TreeNode('', null, null);
|
if (maxDepth === curDepth) return new TreeNode('', null, null);
|
||||||
return new TreeNode(
|
return new TreeNode(values[curDepth], buildTree(maxDepth, values, curDepth + 1),
|
||||||
values[curDepth],
|
|
||||||
buildTree(maxDepth, values, curDepth+1),
|
|
||||||
buildTree(maxDepth, values, curDepth + 1));
|
buildTree(maxDepth, values, curDepth + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,10 +219,7 @@ class BaseLineIf {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'app'})
|
@Component({selector: 'app'})
|
||||||
@View({
|
@View({directives: [TreeComponent], template: `<tree [data]='initData'></tree>`})
|
||||||
directives: [TreeComponent],
|
|
||||||
template: `<tree [data]='initData'></tree>`
|
|
||||||
})
|
|
||||||
class AppComponent {
|
class AppComponent {
|
||||||
initData: TreeNode;
|
initData: TreeNode;
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -240,15 +229,12 @@ class AppComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({selector: 'tree', properties: ['data']})
|
||||||
selector: 'tree',
|
|
||||||
properties: ['data']
|
|
||||||
})
|
|
||||||
@View({
|
@View({
|
||||||
directives: [TreeComponent, NgIf],
|
directives: [TreeComponent, NgIf],
|
||||||
template: `<span> {{data.value}} <span template='ng-if data.right != null'><tree [data]='data.right'></tree></span><span template='ng-if data.left != null'><tree [data]='data.left'></tree></span></span>`
|
template:
|
||||||
|
`<span> {{data.value}} <span template='ng-if data.right != null'><tree [data]='data.right'></tree></span><span template='ng-if data.left != null'><tree [data]='data.left'></tree></span></span>`
|
||||||
})
|
})
|
||||||
class TreeComponent {
|
class TreeComponent {
|
||||||
data: TreeNode;
|
data: TreeNode;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue