From c79f0c3472a23ee4ba36c90a6fb87caa2957e610 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Sun, 28 Sep 2014 13:55:01 -0700 Subject: [PATCH] refactor: simplify and make tests work in JS and Dart * remove `wraps` syntax enhancements for imports and support new `import * as module from ...` syntax - default imports are the wrong construct for importing everything from a module * moved tests from transpiler to jasmine and karma - transpiler tests are included when running karma in main project folder - transpiler is reloaded after every test run in karma, so no need to restart karma when the transpiler has been changed. - removed own gulp build for transpiler and `postinstall.sh` as they are no more needed. - transpiler tests are now executed in Dart AND JavaScript (used to be executed only in Dart), which allowed to catch some bugs (see the bug with the import specification above). * made tests work in dart as well by using the following hack: - dependencies are loaded from the `build` folder, which makes running `gulp build` necessary before running karma for dart - for this to work, the dependencies are included in main `pubspec.yaml` of project - reason for the hack: `karma-dart` loads all `packages` urls directly from disc (should rather use the karma file list) * added explicit annotations `FIELD`, `ABSTRACT`, ... to `facade/lang.*` - needed for now that we can run tests and don't get errors for undefined annotations. * added `README.md` with details about the build and tests --- README.md | 49 +++++ TODO.md | 2 - file2modulename.js | 18 ++ gulpfile.js | 61 ++---- karma-dart.conf.js | 33 +-- karma-js.conf.js | 17 +- karma-mock-annotations.js | 6 - modules/change_detection/pubspec.yaml | 2 + .../change_detection/src/change_detection.js | 1 + modules/change_detection/src/record.js | 23 +- modules/change_detection/src/watch_group.js | 1 + modules/core/src/annotations/directive.js | 2 + modules/core/src/compiler/compiler.js | 1 + modules/core/src/compiler/element_injector.js | 2 +- modules/core/src/compiler/view.js | 4 +- modules/core/src/life_cycle/life_cycle.js | 6 +- modules/core/test/compiler/compiler_spec.js | 8 +- modules/core/test/compiler/view_spec.js | 10 +- modules/di/src/module.js | 3 +- modules/facade/src/dom.dart | 7 +- modules/facade/src/lang.dart | 10 +- modules/facade/src/lang.es6 | 12 +- modules/test_lib/src/test_lib.dart | 2 +- modules/test_lib/src/test_lib.es6 | 2 + postinstall.sh | 7 - pubspec.yaml | 19 +- test-main.dart | 24 +++ test-main.js | 10 +- tools/transpiler/LICENSE | 202 ------------------ tools/transpiler/gulpfile.js | 18 -- tools/transpiler/index.js | 3 +- .../transpiler/karma-traceur-preprocessor.js | 14 +- tools/transpiler/package.json | 26 --- tools/transpiler/pubspec.yaml | 10 - tools/transpiler/run_specs.dart | 7 - tools/transpiler/spec/annotations_spec.js | 17 +- tools/transpiler/spec/classes_spec.js | 16 +- tools/transpiler/spec/equals_spec.js | 18 +- .../transpiler/spec/fixtures/annotations.dart | 20 +- .../transpiler/spec/fixtures/annotations.es6 | 18 ++ tools/transpiler/spec/fixtures/facade.es6 | 3 + tools/transpiler/spec/functions_spec.js | 10 +- tools/transpiler/spec/imports_spec.js | 34 +-- tools/transpiler/spec/runner.dart.template | 13 -- tools/transpiler/spec/types_spec.js | 27 ++- tools/transpiler/src/dart_writer.js | 21 +- tools/transpiler/src/parser.js | 27 --- 47 files changed, 338 insertions(+), 508 deletions(-) create mode 100644 README.md create mode 100644 file2modulename.js delete mode 100644 karma-mock-annotations.js delete mode 100755 postinstall.sh create mode 100644 test-main.dart delete mode 100644 tools/transpiler/LICENSE delete mode 100644 tools/transpiler/gulpfile.js delete mode 100644 tools/transpiler/package.json delete mode 100644 tools/transpiler/pubspec.yaml delete mode 100644 tools/transpiler/run_specs.dart create mode 100644 tools/transpiler/spec/fixtures/annotations.es6 create mode 100644 tools/transpiler/spec/fixtures/facade.es6 delete mode 100644 tools/transpiler/spec/runner.dart.template diff --git a/README.md b/README.md new file mode 100644 index 0000000000..f0f470f7e5 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +## Build + +### Prerequisites: + +1. `npm install` +2. `pub get` +3. `install -g gulp` +4. `install -g karma` + +### Folder structure + +* `modules/*`: modules that will be loaded in the browser +* `tools/*`: tools that are needed to build Angular + +### File endings + +* `*.js`: javascript files that get transpiled to Dart and EcmaScript 5 +* `*.es6`: javascript files that get transpiled only to EcmaScript 5 +* `*.es5`: javascript files that don't get transpiled +* `*.dart`: dart files that don't get transpiled + +### Build: + +1. `gulp build` -> result is in `build` folder + + * will also to `pubg get` for the subfolders in `modules` + and run `dartanalyzer` for every file that matches + `/src/.dart`, e.g. `di/src/di.dart` + +2. `gulp clean` -> cleans the `build` folder + +### Tests: + +1. `karma start karma-js.conf.js`: JS tests +2. `karma start karma-dart.conf.js`: JS tests + +Notes for all tests: + +The karma preprocessor is setup in a way so that after every test run +the transpiler is reloaded. With that it is possible to make changes +to the preprocessor and run the tests without exiting karma +(just touch a test file that you would like to run). + +Restriction for Dart tests (for now): + + * Due to a bug `karma-dart` plugin, + this will use the files in the `build` folder for resolving + `package:` dependencies (created e.g. for `import ... from 'di:di'`). + So you need to execute `gulp build` before this. \ No newline at end of file diff --git a/TODO.md b/TODO.md index 3334c11d0d..5a20546747 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,4 @@ ## Setup -- use package.json's out of the individual projects - - auto start Chromium when start serving - auto refresh Chromium when s/t changed - transform index.html: diff --git a/file2modulename.js b/file2modulename.js new file mode 100644 index 0000000000..fff3c8e0db --- /dev/null +++ b/file2modulename.js @@ -0,0 +1,18 @@ +function file2moduleName(filePath) { + return filePath + // module name should not include non word characters (e.g. '-') + // -> important for Dart + .replace(/[^\w.\/]/g, '_') + // module name should be relative to `modules` and `tools` folder + .replace(/.*\/modules\//, '') + .replace(/.*\/tools\//, '') + // module name should not include `src`, `test`, `lib` + .replace(/\/src\//, '/') + .replace(/\/lib\//, '/') + .replace(/\/test\//, '/') + // module name should not have a suffix + .replace(/\.\w*$/, ''); +} +if (typeof module !== 'undefined') { + module.exports = file2moduleName; +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 49e51e8b3c..68017bae83 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,10 +10,7 @@ var glob = require('glob'); var ejs = require('gulp-ejs'); var path = require('path'); var through2 = require('through2'); - -// import transpiler build tasks -var transpilerTasks = require('./tools/transpiler/gulp-tasks'); -transpilerTasks.install(gulp); +var file2moduleName = require('./file2modulename'); var js2es5Options = { annotations: true, // parse annotations @@ -24,7 +21,7 @@ var js2es5Options = { typeAssertions: true }; -var transpilerOptions = { +var js2dartOptions = { annotations: true, // parse annotations types: true, // parse types script: false, // parse as a module @@ -33,37 +30,20 @@ var transpilerOptions = { var gulpTraceur = require('./tools/transpiler/gulp-traceur'); -function resolveModuleName(fileName) { - var moduleName = fileName - .replace(/.*\/modules\//, '') - .replace(/\/src\//, '/') - .replace(/\/lib\//, '/') - .replace(/\/test\//, '/'); - return moduleName; -} - - // --------- -// rtts-assert and traceur runtime +// traceur runtime gulp.task('jsRuntime/build', function() { - return createJsRuntimeTask(false); -}); - -function createJsRuntimeTask(isWatch) { - var srcFn = isWatch ? watch : gulp.src.bind(gulp); - var traceurRuntime = srcFn(gulpTraceur.RUNTIME_PATH) + var traceurRuntime = gulp.src(gulpTraceur.RUNTIME_PATH) .pipe(gulp.dest('build/js')); return traceurRuntime; -} +}); // ----------------------- // modules var sourceTypeConfigs = { dart: { - compiler: function() { - return gulpTraceur(transpilerOptions, resolveModuleName); - }, + compilerOptions: js2dartOptions, transpileSrc: ['modules/**/*.js'], htmlSrc: ['modules/*/src/**/*.html'], copySrc: ['modules/**/*.dart', 'modules/**/*.yaml'], @@ -82,9 +62,7 @@ var sourceTypeConfigs = { } }, js: { - compiler: function() { - return gulpTraceur(js2es5Options, resolveModuleName); - }, + compilerOptions: js2es5Options, transpileSrc: ['modules/**/*.js', 'modules/**/*.es6'], htmlSrc: ['modules/*/src/**/*.html'], copySrc: ['modules/**/*.es5'], @@ -103,7 +81,7 @@ gulp.task('modules/clean', function() { }); gulp.task('modules/build.dart/src', function() { - return createModuleTask(sourceTypeConfigs.dart, false); + return createModuleTask(sourceTypeConfigs.dart); }); gulp.task('modules/build.dart/analyzer', function() { @@ -125,26 +103,25 @@ gulp.task('modules/build.dart', function(done) { }); gulp.task('modules/build.js', function() { - return createModuleTask(sourceTypeConfigs.js, false); + return createModuleTask(sourceTypeConfigs.js); }); function renameSrcToLib(file) { file.dirname = file.dirname.replace(/\bsrc\b/, 'lib'); } -function createModuleTask(sourceTypeConfig, isWatch) { - var start = isWatch ? watch : gulp.src.bind(gulp); - var transpile = start(sourceTypeConfig.transpileSrc) +function createModuleTask(sourceTypeConfig) { + var transpile = gulp.src(sourceTypeConfig.transpileSrc) .pipe(rename({extname: '.'+sourceTypeConfig.outputExt})) .pipe(rename(renameSrcToLib)) - .pipe(sourceTypeConfig.compiler()) + .pipe(gulpTraceur(sourceTypeConfig.compilerOptions, file2moduleName)) .pipe(gulp.dest(sourceTypeConfig.outputDir)); - var copy = start(sourceTypeConfig.copySrc) + var copy = gulp.src(sourceTypeConfig.copySrc) .pipe(rename(renameSrcToLib)) .pipe(gulp.dest(sourceTypeConfig.outputDir)); // TODO: provide the list of files to the template // automatically! - var html = start(sourceTypeConfig.htmlSrc) + var html = gulp.src(sourceTypeConfig.htmlSrc) .pipe(rename(renameSrcToLib)) .pipe(ejs({ type: sourceTypeConfig.outputExt @@ -177,14 +154,6 @@ gulp.task('serve', connect.server({ // -------------- // general targets -gulp.task('clean', ['transpiler/clean', 'modules/clean']); +gulp.task('clean', ['modules/clean']); gulp.task('build', ['jsRuntime/build', 'modules/build.dart', 'modules/build.js']); - -gulp.task('watch', function() { - // parallel is important as both streams are infinite! - runSequence(['transpiler/test/watch', 'transpiler/src/watch']); - var dartModuleWatch = createModuleTask(sourceTypeConfigs.dart, true); - var jsModuleWatch = createModuleTask(sourceTypeConfigs.js, true); - return mergeStreams(dartModuleWatch, jsModuleWatch, createJsRuntimeTask(true)); -}); diff --git a/karma-dart.conf.js b/karma-dart.conf.js index 9e820d0a4a..1bbf76a101 100644 --- a/karma-dart.conf.js +++ b/karma-dart.conf.js @@ -1,5 +1,6 @@ // Karma configuration // Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT) +var file2moduleName = require('./file2modulename'); module.exports = function(config) { config.set({ @@ -7,11 +8,12 @@ module.exports = function(config) { frameworks: ['dart-unittest'], files: [ - {pattern: 'packages/**/*.dart', included: false}, - {pattern: 'modules/*/src/**/*.js', included: false}, - {pattern: 'modules/*/test/**/*.js', included: true}, - {pattern: 'modules/**/*.dart', included: false}, - 'packages/browser/dart.js' + {pattern: 'modules/**/*_spec.js', included: true}, + {pattern: 'modules/*/src/**/*', included: false}, + {pattern: 'modules/*/test/**/*', included: false}, + {pattern: 'tools/transpiler/spec/**/*_spec.js', included: true}, + {pattern: 'tools/transpiler/spec/**/*', included: false}, + 'test-main.dart' ], karmaDartImports: { @@ -19,18 +21,9 @@ module.exports = function(config) { }, preprocessors: { - 'modules/**/*.js': ['traceur'] + 'modules/**/*.js': ['traceur'], + 'tools/**/*.js': ['traceur'] }, - customFileHandlers: [{ - urlRegex: /.*\/packages\/.*$/, - handler: function(request, response, fa, fb, basePath) { - var url = request.url; - var path = url.indexOf('?') > -1 ? url.substring(0, url.indexOf('?')) : url; - var contets = fs.readFileSync(basePath + path); - response.writeHead(200); - response.end(contets); - } - }], traceurPreprocessor: { options: { outputLanguage: 'dart', @@ -41,13 +34,7 @@ module.exports = function(config) { // typeAssertionModule: 'assert', annotations: true }, - resolveModuleName: function(fileName) { - var moduleName = fileName - .replace(/.*\/modules\//, '') - .replace(/\/src\//, '/') - .replace(/\/test\//, '/'); - return moduleName; - }, + resolveModuleName: file2moduleName, transformPath: function(fileName) { return fileName.replace('.js', '.dart'); } diff --git a/karma-js.conf.js b/karma-js.conf.js index c4237c5ad6..796512198c 100644 --- a/karma-js.conf.js +++ b/karma-js.conf.js @@ -1,5 +1,6 @@ // Karma configuration // Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT) +var file2moduleName = require('./file2modulename'); module.exports = function(config) { config.set({ @@ -8,16 +9,20 @@ module.exports = function(config) { files: [ 'node_modules/traceur/bin/traceur-runtime.js', - './karma-mock-annotations.js', 'modules/**/test_lib/**/*.es6', 'modules/**/*.js', 'modules/**/*.es6', + 'tools/transpiler/spec/**/*.js', + 'tools/transpiler/spec/**/*.es6', + 'file2modulename.js', 'test-main.js' ], preprocessors: { 'modules/**/*.js': ['traceur'], - 'modules/**/*.es6': ['traceur'] + 'modules/**/*.es6': ['traceur'], + 'tools/transpiler/**/*.js': ['traceur'], + 'tools/transpiler/**/*.es6': ['traceur'], }, traceurPreprocessor: { @@ -30,13 +35,7 @@ module.exports = function(config) { typeAssertionModule: 'rtts_assert/rtts_assert', annotations: true }, - resolveModuleName: function(fileName) { - var moduleName = fileName - .replace(/.*\/modules\//, '') - .replace(/\/src\//, '/') - .replace(/\/test\//, '/'); - return moduleName; - }, + resolveModuleName: file2moduleName, transformPath: function(fileName) { return fileName.replace('.es6', ''); } diff --git a/karma-mock-annotations.js b/karma-mock-annotations.js deleted file mode 100644 index 76291bd251..0000000000 --- a/karma-mock-annotations.js +++ /dev/null @@ -1,6 +0,0 @@ - -// TODO: Remove these annotations in the JS traceur build as they are only needed in Dart -window.FIELD = function() {}; -window.IMPLEMENTS = function() {}; -window.CONST = function() {}; -window.List = Array; diff --git a/modules/change_detection/pubspec.yaml b/modules/change_detection/pubspec.yaml index 70f6b4688a..9f912e20ce 100644 --- a/modules/change_detection/pubspec.yaml +++ b/modules/change_detection/pubspec.yaml @@ -5,3 +5,5 @@ dependencies: dev_dependencies: test_lib: path: ../test_lib + facade: + path: ../facade diff --git a/modules/change_detection/src/change_detection.js b/modules/change_detection/src/change_detection.js index e96fbe4e6b..f0415a07da 100644 --- a/modules/change_detection/src/change_detection.js +++ b/modules/change_detection/src/change_detection.js @@ -1,5 +1,6 @@ import {WatchGroup} from './watch_group'; import {Record} from './record'; +import {FIELD} from 'facade/lang'; export class ChangeDetection { diff --git a/modules/change_detection/src/record.js b/modules/change_detection/src/record.js index b2e8cc6159..b74bbe4dcc 100644 --- a/modules/change_detection/src/record.js +++ b/modules/change_detection/src/record.js @@ -1,4 +1,5 @@ //import {ProtoWatchGroup, WatchGroup} from './watch_group'; +import {FIELD} from 'facade/lang'; export class ProtoRecord { @@ -53,28 +54,28 @@ export class ProtoRecord { /** * Represents a Record for keeping track of changes. A change is a difference between previous - * and current value. - * + * and current value. + * * By default changes are detected using dirty checking, but a notifier can be present which can * notify the records of changes by means other than dirty checking. For example Object.observe * or events on DOM elements. - * - * DESIGN NOTES: - * - No inheritance allowed so that code is monomorphic for performance. + * + * DESIGN NOTES: + * - No inheritance allowed so that code is monomorphic for performance. * - Atomic watch operations * - Defaults to dirty checking * - Keep this object as lean as possible. (Lean in number of fields) - * + * * MEMORY COST: 13 Words; */ export class Record { - + @FIELD('final watchGroup:WatchGroup') @FIELD('final protoRecord:ProtoRecord') /// order list of all records. Including head/tail markers @FIELD('_next:Record') @FIELD('_prev:Record') - /// next record to dirty check + /// next record to dirty check @FIELD('_checkNext:Record') @FIELD('_checkPrev:Record') // next notifier @@ -120,7 +121,7 @@ export class Record { var notify = mode & MODE_MASK_NOTIFY; var currentValue; switch (state) { - case MODE_STATE_MARKER: + case MODE_STATE_MARKER: return false; case MODE_STATE_PROPERTY: currentValue = this._getter(this._context); @@ -136,7 +137,7 @@ export class Record { } var previousValue = this.previousValue; if (isSame(previousValue, currentValue)) return false; - if (previousValue instanceof String && currentValue instanceof String + if (previousValue instanceof String && currentValue instanceof String && previousValue == currentValue) { this.previousValue = currentValue; return false @@ -178,4 +179,4 @@ function isSame(a, b) { } else { return false; } -} +} diff --git a/modules/change_detection/src/watch_group.js b/modules/change_detection/src/watch_group.js index 05655bb8a0..3598c67d7b 100644 --- a/modules/change_detection/src/watch_group.js +++ b/modules/change_detection/src/watch_group.js @@ -1,4 +1,5 @@ import {ProtoRecord, Record} from './record'; +import {FIELD} from 'facade/lang'; export class ProtoWatchGroup { @FIELD('final _headRecord:ProtoRecord') diff --git a/modules/core/src/annotations/directive.js b/modules/core/src/annotations/directive.js index 40df6161f8..c8493dfcb7 100644 --- a/modules/core/src/annotations/directive.js +++ b/modules/core/src/annotations/directive.js @@ -1,5 +1,7 @@ import {Type} from 'facade/lang'; import {ElementServicesFunction} from './facade'; +import {ABSTRACT} from 'facade/lang'; + @ABSTRACT export class Directive { diff --git a/modules/core/src/compiler/compiler.js b/modules/core/src/compiler/compiler.js index 0fa574baf6..a9048795f3 100644 --- a/modules/core/src/compiler/compiler.js +++ b/modules/core/src/compiler/compiler.js @@ -2,6 +2,7 @@ import {Future, Type} from 'facade/lang'; import {Element} from 'facade/dom'; import {ProtoView} from './view'; import {TemplateLoader} from './template_loader'; +import {FIELD} from 'facade/lang'; export class Compiler { diff --git a/modules/core/src/compiler/element_injector.js b/modules/core/src/compiler/element_injector.js index 135edb2a86..33dc688a7f 100644 --- a/modules/core/src/compiler/element_injector.js +++ b/modules/core/src/compiler/element_injector.js @@ -1,4 +1,4 @@ - +import {FIELD} from 'facade/lang'; /** diff --git a/modules/core/src/compiler/view.js b/modules/core/src/compiler/view.js index d7032b4149..1b839a5700 100644 --- a/modules/core/src/compiler/view.js +++ b/modules/core/src/compiler/view.js @@ -1,10 +1,12 @@ import {DOM, Node, DocumentFragment, TemplateElement} from 'facade/dom'; -import {ListWrapper wraps List} from 'facade/collection'; +import {ListWrapper} from 'facade/collection'; import {ProtoWatchGroup, WatchGroup, WatchGroupDispatcher} from 'change_detection/watch_group'; import {Record} from 'change_detection/record'; import {Module} from 'di/di'; import {ProtoElementInjector, ElementInjector} from './element_injector'; import {SetterFn} from 'change_detection/facade'; +import {FIELD, IMPLEMENTS} from 'facade/lang'; +import {List} from 'facade/collection'; @IMPLEMENTS(WatchGroupDispatcher) export class View { diff --git a/modules/core/src/life_cycle/life_cycle.js b/modules/core/src/life_cycle/life_cycle.js index 5185b7ce95..62513eec52 100644 --- a/modules/core/src/life_cycle/life_cycle.js +++ b/modules/core/src/life_cycle/life_cycle.js @@ -1,9 +1,11 @@ +import {FIELD} from 'facade/lang'; + export class LifeCycle { - + @FIELD('final _changeDetection:ChangeDetection') @FIELD('final _onChangeDispatcher:OnChangeDispatcher') constructor() {} - + digest() { _changeDetection.detectChanges(); _onChangeDispatcher.done(); diff --git a/modules/core/test/compiler/compiler_spec.js b/modules/core/test/compiler/compiler_spec.js index aef400851f..b087e86467 100644 --- a/modules/core/test/compiler/compiler_spec.js +++ b/modules/core/test/compiler/compiler_spec.js @@ -1,9 +1,9 @@ -import {describe, id} from 'test_lib/test_lib'; -import {Compiler} from './compiler'; +import {describe, it, expect} from 'test_lib/test_lib'; +import {Compiler} from 'core/compiler/compiler'; export function main() { - describe('compiler', () => { - it('should hello', () => { + describe('compiler', function() { + it('should hello', function() { print('I am working'); }); }); diff --git a/modules/core/test/compiler/view_spec.js b/modules/core/test/compiler/view_spec.js index 4c86e413cd..0eb7d4793c 100644 --- a/modules/core/test/compiler/view_spec.js +++ b/modules/core/test/compiler/view_spec.js @@ -1,11 +1,11 @@ -import {describe, id} from 'test_lib/test_lib'; -import {ProtoView, View} from './view'; +import {describe, it, expect} from 'test_lib/test_lib'; +import {ProtoView, View} from 'core/compiler/view'; import {DOM} from 'facade/dom'; export function main() { - describe('view', () => { - describe('ProtoView', () => { - it('should create an instance of view', () => { + describe('view', function() { + describe('ProtoView', function() { + it('should create an instance of view', function() { var template = DOM.createTemplate('Hello world!'); var pv = new ProtoView(template, null, null, null); var view:View = pv.instantiate(); diff --git a/modules/di/src/module.js b/modules/di/src/module.js index 62cf0bb562..80d6018593 100644 --- a/modules/di/src/module.js +++ b/modules/di/src/module.js @@ -1,5 +1,6 @@ +import {FIELD} from 'facade/lang'; import {Type} from 'facade/lang'; -import {Map, MapWrapper wraps Map} from 'facade/collection'; +import {Map, MapWrapper} from 'facade/collection'; import {Key} from './key'; /// becouse we need to know when toValue was not set. diff --git a/modules/facade/src/dom.dart b/modules/facade/src/dom.dart index 39c9907cc2..bafe427424 100644 --- a/modules/facade/src/dom.dart +++ b/modules/facade/src/dom.dart @@ -14,12 +14,17 @@ class DOM { static getInnerHTML(el) { return el.innerHtml; } - static setInnerHTML(el:, value) { + static setInnerHTML(el, value) { el.innerHtml = value; } static setText(Text text, String value) { text.text = value; } + static createTemplate(html) { + var t = document.createElement('template'); + t.setInnerHtml(html); + return t; + } static clone(Node node) { return node.clone(true); } diff --git a/modules/facade/src/lang.dart b/modules/facade/src/lang.dart index bfea25f1ec..b8f72fd59c 100644 --- a/modules/facade/src/lang.dart +++ b/modules/facade/src/lang.dart @@ -1,4 +1,12 @@ library angular.core.facade.async; export 'dart:async' show Future; -export 'dart:core' show Type; \ No newline at end of file +export 'dart:core' show Type; + +class FIELD { + const constructor(this.definition); +} + +class CONST {} +class ABSTRACT {} +class IMPLEMENTS {} \ No newline at end of file diff --git a/modules/facade/src/lang.es6 b/modules/facade/src/lang.es6 index 12d7f60c9a..2d197307f1 100644 --- a/modules/facade/src/lang.es6 +++ b/modules/facade/src/lang.es6 @@ -1,2 +1,12 @@ export var Future = Promise; -export var Type = Function; \ No newline at end of file +export var Type = Function; + +export class FIELD { + constructor(definition) { + this.definition = definition; + } +} + +export class CONST {} +export class ABSTRACT {} +export class IMPLEMENTS {} \ No newline at end of file diff --git a/modules/test_lib/src/test_lib.dart b/modules/test_lib/src/test_lib.dart index 812d464e61..8eeb377a79 100644 --- a/modules/test_lib/src/test_lib.dart +++ b/modules/test_lib/src/test_lib.dart @@ -1 +1 @@ -export 'package:guinness/guinness.dart' show describe, it, beforeEach, afterEach, expect; +export 'package:guinness/guinness.dart' show describe, ddescribe, it, iit, beforeEach, afterEach, expect; diff --git a/modules/test_lib/src/test_lib.es6 b/modules/test_lib/src/test_lib.es6 index 72d70ed3c2..c4ed0f7109 100644 --- a/modules/test_lib/src/test_lib.es6 +++ b/modules/test_lib/src/test_lib.es6 @@ -1,5 +1,7 @@ export var describe = window.describe; +export var ddescribe = window.ddescribe; export var it = window.it; +export var iit = window.iit; export var beforeEach = window.beforeEach; export var afterEach = window.afterEach; export var expect = window.expect; diff --git a/postinstall.sh b/postinstall.sh deleted file mode 100755 index f7c5192fc6..0000000000 --- a/postinstall.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh -git submodule init && git submodule update - -rm node_modules/transpiler -ln -s ../tools/transpiler node_modules/transpiler - -(cd tools/transpiler; npm install) diff --git a/pubspec.yaml b/pubspec.yaml index 0a174e8213..ce83bf4e7d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,14 +1,17 @@ name: angular -version: 0.0.0 -authors: -- Vojta Jina -description: Angular environment: sdk: '>=1.4.0' dependencies: -dev_dependencies: test_lib: - path: modules/test_lib - unittest: '>=0.10.1 <0.12.0' + path: build/dart/test_lib + facade: + path: build/dart/facade + core: + path: build/dart/core + di: + path: build/dart/di + change_detection: + path: build/dart/change_detection + +dev_dependencies: guinness: ">=0.1.5 <0.2.0" - browser: '>=0.10.0 <0.11.0' diff --git a/test-main.dart b/test-main.dart new file mode 100644 index 0000000000..568c38702e --- /dev/null +++ b/test-main.dart @@ -0,0 +1,24 @@ +import 'package:guinness/guinness.dart'; +import 'package:unittest/unittest.dart' as unit; + +main() { + unit.filterStacks = true; + unit.formatStacks = false; + + _printWarnings(); + + guinness.autoInit = false; + guinness.initSpecs(); +} + +_printWarnings () { + final info = guinness.suiteInfo(); + + if (info.activeIts.any((it) => it.exclusive)) { + print("WARN: iit caused some tests to be excluded"); + } + + if (info.exclusiveDescribes.isNotEmpty) { + print("WARN: ddescribe caused some tests to be excluded"); + } +} \ No newline at end of file diff --git a/test-main.js b/test-main.js index 0ba9fe3b8e..cc7a128480 100644 --- a/test-main.js +++ b/test-main.js @@ -1,14 +1,10 @@ -var TEST_REGEXP = /^\/base\/modules\/[^\/]*\/test\/.*/; +var TEST_REGEXP = /_spec.*/; Object.keys(window.__karma__.files).forEach(function(path) { if (TEST_REGEXP.test(path)) { - var moduleName = path - .replace(/.*\/modules\//, '') - .replace(/\/src\//, '/') - .replace(/\/test\//, '/') - .replace(/\.\w*$/, ''); + var moduleName = window.file2moduleName(path); var mod = System.get(moduleName); - if (mod.main) { + if (mod && mod.main) { mod.main(); } } diff --git a/tools/transpiler/LICENSE b/tools/transpiler/LICENSE deleted file mode 100644 index e06d208186..0000000000 --- a/tools/transpiler/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/tools/transpiler/gulpfile.js b/tools/transpiler/gulpfile.js deleted file mode 100644 index d3531ab79d..0000000000 --- a/tools/transpiler/gulpfile.js +++ /dev/null @@ -1,18 +0,0 @@ -var gulp = require('gulp'); -var tasks = require('./gulp-tasks'); -var runSequence = require('run-sequence'); -var watch = require('gulp-watch'); -var mergeStreams = require('event-stream').merge; - -tasks.install(gulp); - -gulp.task('test', function() { - return runSequence('transpiler/test'); -}); - -gulp.task('clean', ['transpiler/clean']); - -gulp.task('watch', function(done) { - // parallel is important as both streams are infinite! - runSequence(['transpiler/test/watch', 'transpiler/src/watch'], done); -}); \ No newline at end of file diff --git a/tools/transpiler/index.js b/tools/transpiler/index.js index f5e7659f6b..0f28b7c391 100644 --- a/tools/transpiler/index.js +++ b/tools/transpiler/index.js @@ -16,8 +16,7 @@ var SELF_COMPILE_OPTIONS = { var needsReload = true; -// TODO(vojta): call this if sources changed -exports.sourcesChanged = function() { +exports.reloadSources = function() { needsReload = true; }; diff --git a/tools/transpiler/karma-traceur-preprocessor.js b/tools/transpiler/karma-traceur-preprocessor.js index 03ac8f7a86..26a09f7d67 100644 --- a/tools/transpiler/karma-traceur-preprocessor.js +++ b/tools/transpiler/karma-traceur-preprocessor.js @@ -4,11 +4,17 @@ module.exports = { 'preprocessor:traceur': ['factory', createJs2DartPreprocessor] }; -function createJs2DartPreprocessor(logger, basePath, config) { +function createJs2DartPreprocessor(logger, basePath, config, emitter) { var log = logger.create('traceur'); - + // Reload the transpiler sources so we don't need to + // restart karma when we made changes to traceur. + // As there is no event that is called before any preprocessor runs, + // we listen for the end event in karma to reload the + // transpiler sources. + emitter.on('run_complete', function(filesPromise) { + transpiler.reloadSources(); + }); return function(content, file, done) { - try { var moduleName = config.resolveModuleName(file.originalPath); if (config.transformPath) { @@ -34,4 +40,4 @@ function createJs2DartPreprocessor(logger, basePath, config) { }; } -createJs2DartPreprocessor.$inject = ['logger', 'config.basePath', 'config.traceurPreprocessor']; +createJs2DartPreprocessor.$inject = ['logger', 'config.basePath', 'config.traceurPreprocessor', 'emitter']; diff --git a/tools/transpiler/package.json b/tools/transpiler/package.json deleted file mode 100644 index d456e05c93..0000000000 --- a/tools/transpiler/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "transpiler", - "version": "0.0.0", - "description": "Compile JavaScript to Dart so that you can compile it back to JavaScript and run.", - "main": "index.js", - "scripts": { - "test": "gulp transpiler/test", - "postinstall": "pub install" - }, - "author": "Vojta Jina ", - "license": "MIT", - "devDependencies": { - "gulp": "^3.8.8", - "gulp-rename": "^1.2.0", - "gulp-shell": "^0.2.9", - "gulp-watch": "^1.0.3", - "q": "^1.0.1", - "through2": "^0.6.1", - "event-stream": "^3.1.5", - "gulp-rimraf": "^0.1.0", - "run-sequence": "^0.3.6", - "glob": "^4.0.6", - "gulp-ejs": "^0.3.1", - "traceur": "^0.0.66" - } -} diff --git a/tools/transpiler/pubspec.yaml b/tools/transpiler/pubspec.yaml deleted file mode 100644 index 90a31db5a0..0000000000 --- a/tools/transpiler/pubspec.yaml +++ /dev/null @@ -1,10 +0,0 @@ -name: transpiler -version: 0.0.0 -authors: -- Vojta Jina -description: Compile JavaScript to Dart so that you can compile it back to JavaScript and run. -environment: - sdk: '>=1.4.0' -dependencies: -dev_dependencies: - unittest: '>=0.10.1 <0.12.0' diff --git a/tools/transpiler/run_specs.dart b/tools/transpiler/run_specs.dart deleted file mode 100644 index 94d4de6d1c..0000000000 --- a/tools/transpiler/run_specs.dart +++ /dev/null @@ -1,7 +0,0 @@ -// Note: need this file here so that we can use the packages -// in the main folder... -import './build/spec/runner.dart' as runner; - -void main() { - runner.main(); -} diff --git a/tools/transpiler/spec/annotations_spec.js b/tools/transpiler/spec/annotations_spec.js index 4cf4971887..d867fda1f3 100644 --- a/tools/transpiler/spec/annotations_spec.js +++ b/tools/transpiler/spec/annotations_spec.js @@ -1,19 +1,26 @@ -import annotations from './fixtures/annotations'; +import {describe, it, expect} from 'test_lib/test_lib'; +import {Provide, readFirstAnnotation} from './fixtures/annotations'; class Inject {} class Bar {} -@annotations.Provide('Foo') +@Provide('Foo') class Foo { @Inject constructor() {} } -@annotations.Provide(Foo) +@Provide(Foo) function baz() {} function annotatedParams(@Inject(Foo) f, @Inject(Bar) b) {} -function main() { - annotations.main(); +export function main() { + describe('annotations', function() { + it('should work', function() { + // Assert `Foo` class has `Provide` annotation. + var clazz = readFirstAnnotation(Foo); + expect(clazz instanceof Provide).toBe(true); + }); + }); } \ No newline at end of file diff --git a/tools/transpiler/spec/classes_spec.js b/tools/transpiler/spec/classes_spec.js index f5d317afd3..6953365cec 100644 --- a/tools/transpiler/spec/classes_spec.js +++ b/tools/transpiler/spec/classes_spec.js @@ -1,3 +1,5 @@ +import {describe, it, expect} from 'test_lib/test_lib'; + // Constructor // Define fields class Foo { @@ -11,10 +13,14 @@ class Foo { } } -function main() { - var foo = new Foo(2, 3); +export function main() { + describe('classes', function() { + it('should work', function() { + var foo = new Foo(2, 3); - assert(foo.a == 2); - assert(foo.b == 3); - assert(foo.sum() == 5); + expect(foo.a).toBe(2); + expect(foo.b).toBe(3); + expect(foo.sum()).toBe(5); + }); + }); } diff --git a/tools/transpiler/spec/equals_spec.js b/tools/transpiler/spec/equals_spec.js index f4a7edbc47..628d3d65df 100644 --- a/tools/transpiler/spec/equals_spec.js +++ b/tools/transpiler/spec/equals_spec.js @@ -1,3 +1,5 @@ +import {describe, it, expect} from 'test_lib/test_lib'; + function same(a, b) { return a === b; } @@ -7,10 +9,14 @@ function notSame(a, b) { return a !== b; } -function main() { - var obj = {}; - assert(same({}, {}) == false); - assert(same(obj, obj) == true); - assert(notSame({}, {}) == true); - assert(notSame(obj, obj) == false); +export function main() { + describe('equals', function() { + it('should work', function() { + var obj = {}; + expect(same({}, {}) == false).toBe(true); + expect(same(obj, obj) == true).toBe(true); + expect(notSame({}, {}) == true).toBe(true); + expect(notSame(obj, obj) == false).toBe(true); + }); + }); } diff --git a/tools/transpiler/spec/fixtures/annotations.dart b/tools/transpiler/spec/fixtures/annotations.dart index 2341a9e4f1..87bb5fb810 100644 --- a/tools/transpiler/spec/fixtures/annotations.dart +++ b/tools/transpiler/spec/fixtures/annotations.dart @@ -1,26 +1,18 @@ -// This file is not generated, +import 'dart:mirrors'; + +// This class is not generated, // but should be in the future. // // Problems: // - Dart requires annotations to be const (which makes sense). // Right now, I can't describe that in ES6. -// - operator mapping `is`/`instanceof` is not yet implemented -import 'dart:mirrors'; - -import '../annotations_spec.dart'; - class Provide { final token; const Provide(this.token); } -readAnnotation(clazz) { +// TODO: this api does not yet return an array as we don't have +// a nice array wrapper for Dart +readFirstAnnotation(clazz) { return reflectClass(clazz).metadata.first.reflectee; } - -main() { - // Assert `Foo` class has `Provide` annotation. - // TODO(vojta): test this more. - var clazz = readAnnotation(Foo); - assert(clazz is Provide); -} \ No newline at end of file diff --git a/tools/transpiler/spec/fixtures/annotations.es6 b/tools/transpiler/spec/fixtures/annotations.es6 new file mode 100644 index 0000000000..dfcc83aa18 --- /dev/null +++ b/tools/transpiler/spec/fixtures/annotations.es6 @@ -0,0 +1,18 @@ +// This class is not generated, +// but should be in the future. +// +// Problems: +// - Dart requires annotations to be const (which makes sense). +// Right now, I can't describe that in ES6. +export class Provide { + constructor(token) { + this.token = token; + } +} + + +// TODO: this api does not yet return an array as we don't have +// a nice array wrapper for Dart +export function readFirstAnnotation(clazz) { + return clazz.annotations[0]; +} diff --git a/tools/transpiler/spec/fixtures/facade.es6 b/tools/transpiler/spec/fixtures/facade.es6 new file mode 100644 index 0000000000..c54022ccb5 --- /dev/null +++ b/tools/transpiler/spec/fixtures/facade.es6 @@ -0,0 +1,3 @@ +export class MapWrapper { + +} \ No newline at end of file diff --git a/tools/transpiler/spec/functions_spec.js b/tools/transpiler/spec/functions_spec.js index 73d690f499..cd32f2f0aa 100644 --- a/tools/transpiler/spec/functions_spec.js +++ b/tools/transpiler/spec/functions_spec.js @@ -1,7 +1,13 @@ +import {describe, it, expect} from 'test_lib/test_lib'; + function sum(a, b) { return a + b; } -function main() { - assert(sum(1, 2) == 3); +export function main() { + describe('functions', function() { + it('should work', function() { + expect(sum(1, 2)).toBe(3); + }); + }); } diff --git a/tools/transpiler/spec/imports_spec.js b/tools/transpiler/spec/imports_spec.js index 36ac12f34a..f71941de70 100644 --- a/tools/transpiler/spec/imports_spec.js +++ b/tools/transpiler/spec/imports_spec.js @@ -1,22 +1,28 @@ +import {describe, it, expect} from 'test_lib/test_lib'; + import {Foo, Bar} from './foo'; +// TODO: Does not work, as dart does not support renaming imports // import {Foo as F} from './fixtures/foo'; -import fooModule from './foo'; +import * as fooModule from './foo'; -import {MapWrapper wraps Map} from './fixtures/facade'; +import * as exportModule from './export'; -import exportModule from './export'; +import {Type} from 'facade/lang'; -import unittest from 'unittest/unittest'; +export function main() { + describe('imports', function() { + it('should work', function() { + expect(Foo).toBe('FOO'); + expect(Bar).toBe('BAR'); + // TODO: Does not work + // assert(F == 'FOO'); + expect(fooModule.Foo).toBe('FOO'); + expect(fooModule.Bar).toBe('BAR'); -function main() { - assert(Foo == 'FOO'); - assert(Bar == 'BAR'); - // assert(F == 'FOO'); - assert(fooModule.Foo == 'FOO'); - assert(fooModule.Bar == 'BAR'); + expect(exportModule.Foo).toBe('FOO'); + expect(exportModule.Bar).toBe('BAR'); - assert(exportModule.Foo == 'FOO'); - assert(exportModule.Bar == 'BAR'); - - assert(unittest.PASS != null); + expect(Type).toBeTruthy(); + }); + }); } diff --git a/tools/transpiler/spec/runner.dart.template b/tools/transpiler/spec/runner.dart.template deleted file mode 100644 index 19337d8d5e..0000000000 --- a/tools/transpiler/spec/runner.dart.template +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:unittest/unittest.dart'; - -<% files.forEach(function(file, index) { %> -import '<%= file %>' as spec<%=index%>; -<% }); %> - -void main() { - <% files.forEach(function(file, index) { %> - test('<%= file %>', () { - spec<%= index %>.main(); - }); - <% }); %> -} diff --git a/tools/transpiler/spec/types_spec.js b/tools/transpiler/spec/types_spec.js index 8a5e2122c2..dd192ff9d9 100644 --- a/tools/transpiler/spec/types_spec.js +++ b/tools/transpiler/spec/types_spec.js @@ -1,3 +1,8 @@ +import {describe, it, expect} from 'test_lib/test_lib'; + +class A {} +class B {} + function sum(a: number, b: number): number { return a + b; } @@ -6,7 +11,7 @@ function not(a: boolean): boolean { return !a; } -function generics(a: A) { +function generics(a: A) { } @@ -37,17 +42,21 @@ class Foo { typedVariables() { // TODO(vojta): test this var foo:string = 'foo'; - var typed:bool, untyped; + var typed:boolean, untyped; var oneTyped:string = 'one', - another: bool = true; + another: boolean = true; } } -function main() { - // TODO(vojta): test this better. - var f = new Foo(1, 2); - assert(f.sum() == 3); - assert(f instanceof Foo); +export function main() { + describe('types', function() { + it('should work', function() { + // TODO(vojta): test this better. + var f = new Foo(1, 2); + assert(f.sum() == 3); + assert(f instanceof Foo); - f.typedVariables(); + f.typedVariables(); + }); + }); } \ No newline at end of file diff --git a/tools/transpiler/src/dart_writer.js b/tools/transpiler/src/dart_writer.js index 4c7aae7433..453f9eb8a9 100644 --- a/tools/transpiler/src/dart_writer.js +++ b/tools/transpiler/src/dart_writer.js @@ -6,9 +6,7 @@ import {ParseTreeWriter as JavaScriptParseTreeWriter} from 'traceur/src/outputge export class DartTreeWriter extends JavaScriptParseTreeWriter { constructor(moduleName, outputPath) { super(outputPath); - this.libName = moduleName - .replace(/\//g, '.') - .replace(/[^\w.]/g, '_'); + this.libName = moduleName.replace(/\//g, '.'); } // VARIABLES - types @@ -182,10 +180,9 @@ export class DartTreeWriter extends JavaScriptParseTreeWriter { this.visitAny(tree.moduleSpecifier); if (tree.importClause.binding) { - // Default import - import the entire module. - // import foo from './bar'; - this.write_(' as '); - this.visitAny(tree.importClause.binding); + // Default import, not supported as dart does not distinguish + // between explicit exports and default exports + throw new Error('default imports/exports not supported'); } else { // Regular - import list of members. // import {Foo, Bar} from './baz'; @@ -221,6 +218,16 @@ export class DartTreeWriter extends JavaScriptParseTreeWriter { } } + visitModuleDeclaration(tree) { + // module import - import the entire module. + // import * as foo from './bar'; + this.write_(IMPORT); + this.writeSpace_(); + this.visitAny(tree.expression); + this.write_(' as '); + this.visitAny(tree.binding); + this.write_(SEMI_COLON); + } // ANNOTATIONS // TODO(vojta): this is just fixing a bug in Traceur, send a PR. diff --git a/tools/transpiler/src/parser.js b/tools/transpiler/src/parser.js index 259a8ac3b4..a1ea24bd9e 100644 --- a/tools/transpiler/src/parser.js +++ b/tools/transpiler/src/parser.js @@ -3,8 +3,6 @@ import {SyntaxErrorReporter} from 'traceur/src/util/SyntaxErrorReporter'; import {TypeName, ImportSpecifier, ImportedBinding, BindingIdentifier} from 'traceur/src/syntax/trees/ParseTrees'; import {PERIOD, IMPORT, STAR, AS, FROM, CLOSE_ANGLE, OPEN_ANGLE, COMMA, OPEN_CURLY, CLOSE_CURLY, COLON} from 'traceur/src/syntax/TokenType'; -var WRAPS = 'wraps'; - export class Parser extends TraceurParser { constructor(file, errorReporter = new SyntaxErrorReporter()) { super(file, errorReporter); @@ -26,31 +24,6 @@ export class Parser extends TraceurParser { return typeName; } - parseImportSpecifier_() { - // Copy of original implementation - var start = this.getTreeStartLocation_(); - var token = this.peekToken_(); - var isKeyword = token.isKeyword(); - var binding; - var name = this.eatIdName_(); - // Support for wraps keywoard - if (this.peekToken_().value === WRAPS) { - token = this.nextToken_(); - var wrappedIdentifier = this.eatId_(); - // TODO: Save the fact that this is a wrapper type and - // also the wrapped type - } - // Copy of original implementation - if (isKeyword || this.peekPredefinedString_(AS)) { - this.eatId_(AS); - binding = this.parseImportedBinding_(); - } else { - binding = new ImportedBinding(name.location, new BindingIdentifier(name.location, name)); - name = null; - } - return new ImportSpecifier(this.getTreeLocation_(start), binding, name); - } - parseObjectType_() { //TODO(misko): save the type information this.eat_(OPEN_CURLY);