// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library dev_compiler.test.closure_annotation_test; import 'package:test/test.dart'; import 'package:dev_compiler/src/closure/closure_annotation.dart'; import 'package:dev_compiler/src/js_ast/js_ast.dart' show TypeRef, Identifier; void main() { group('ClosureAnnotation', () { var anyType = new TypeRef.any(); var unknownType = new TypeRef.unknown(); var numberType = new TypeRef.number(); var stringType = new TypeRef.string(); var booleanType = new TypeRef.boolean(); var fooType = new TypeRef.qualified([new Identifier("foo"), new Identifier("Foo")]); var barType = new TypeRef.named("Bar"); var bazType = new TypeRef.named("Baz"); var bamType = new TypeRef.named("Bam"); var batType = new TypeRef.named("Bat"); test('gives empty comment when no has no meaningful info', () { expect(new ClosureAnnotation().toString(), ""); expect(new ClosureAnnotation(type: anyType).toString(), ""); expect(new ClosureAnnotation(type: unknownType).toString(), ""); }); test('gives single line comment when it fits', () { expect(new ClosureAnnotation(type: numberType).toString(), "/** @type {number} */"); expect(new ClosureAnnotation(paramTypes: {'foo': anyType}).toString(), "/** @param {*} foo */"); expect(new ClosureAnnotation(paramTypes: {'foo': unknownType}).toString(), "/** @param {?} foo */"); }); test('gives multiple line comment when it it does not fit on one line', () { expect( new ClosureAnnotation( returnType: stringType, paramTypes: {'foo': numberType}).toString(), "/**\n" " * @param {number} foo\n" " * @return {string}\n" " */"); }); test('inserts indentation', () { expect( new ClosureAnnotation( returnType: stringType, paramTypes: {'foo': numberType}).toString(" "), "/**\n" // No indent on first line. " * @param {number} foo\n" " * @return {string}\n" " */"); }); test('compresses @type, @final, @const, @private, @protected, @typedef', () { expect(new ClosureAnnotation(type: stringType).toString(), "/** @type {string} */"); expect(new ClosureAnnotation(type: stringType, isConst: true).toString(), "/** @const {string} */"); expect(new ClosureAnnotation(type: stringType, isFinal: true).toString(), "/** @final {string} */"); expect( new ClosureAnnotation(type: stringType, isPrivate: true).toString(), "/** @private {string} */"); expect( new ClosureAnnotation(type: stringType, isTypedef: true).toString(), "/** @typedef {string} */"); expect( new ClosureAnnotation(type: stringType, isProtected: true).toString(), "/** @protected {string} */"); expect( new ClosureAnnotation( type: stringType, isPrivate: true, isConst: true, isFinal: true, isProtected: true, isTypedef: true) .toString(), "/** @private @protected @final @const @typedef {string} */"); }); test('supports a full constructor annotation', () { expect( new ClosureAnnotation( returnType: booleanType, throwsType: bamType, thisType: fooType, superType: barType, lendsToType: batType, interfaces: [bazType], isStruct: true, isPrivate: true, isProtected: true, isOverride: true, isFinal: true, isConst: true, isConstructor: true, isNoSideEffects: true, isNoCollapse: true, paramTypes: {'x': stringType, 'y': numberType}, templates: ['A', 'B']).toString(), '/**\n' ' * @template A, B\n' ' * @this {foo.Foo}\n' ' * @override\n' ' * @nosideeffects\n' ' * @nocollapse\n' ' * @lends {Bat}\n' ' * @private @protected @final @const\n' ' * @constructor @struct @extends {Bar}\n' ' * @implements {Baz}\n' ' * @param {string} x\n' ' * @param {number} y\n' ' * @return {boolean}\n' ' * @throws {Bam}\n' ' */'); }); }); }