/*
* Copyright 2013 The Closure Compiler Authors.
*
* 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.
*/
package com.google.javascript.jscomp;
/**
* Tests for type-checking across commonjs modules.
*
* @author nicholas.j.santos@gmail.com (Nick Santos)
*/
public final class CommonJSIntegrationTest extends IntegrationTestCase {
public void testCrossModuleCtorCall() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join("/** @constructor */ function Hello() {}", "module.exports = Hello;"),
LINE_JOINER.join("var Hello = require('./i0');", "var hello = new Hello();")
},
new String[] {
"var module$i0 = function (){};",
LINE_JOINER.join("var Hello = module$i0;", "var hello = new module$i0();")
});
}
public void testCrossModuleCtorCall2() {
test(createCompilerOptions(),
new String[] {
"/** @constructor */ function Hello() {} " +
"module.exports = Hello;",
"var Hello = require('./i0');" +
"var hello = new Hello(1);"
},
TypeCheck.WRONG_ARGUMENT_COUNT);
}
public void testCrossModuleTypeAnnotation() {
test(
createCompilerOptions(),
LINE_JOINER.join(
"/** @constructor */ function Hello() {} ",
"/** @type {!Hello} */ var hello = new Hello();",
"module.exports = Hello;"),
LINE_JOINER.join(
"var module$i0 = function () {};", "var hello$$module$i0 = new module$i0();"));
}
public void testCrossModuleTypeAnnotation2() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join("/** @constructor */ function Hello() {}", "module.exports = Hello;"),
LINE_JOINER.join(
"var Hello = require('./i0');", "/** @type {!Hello} */ var hello = new Hello();")
},
new String[] {
"var module$i0 = function() {};",
LINE_JOINER.join("var Hello = module$i0;", "var hello = new module$i0();")
});
}
public void testCrossModuleTypeAnnotation3() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join("/** @constructor */ function Hello() {}", "module.exports = Hello;"),
LINE_JOINER.join("var Hello = require('./i0');", "/** @type {!Hello} */ var hello = 1;")
},
TypeValidator.TYPE_MISMATCH_WARNING);
}
public void testMultipleExportAssignments1() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join(
"/** @constructor */ function Hello() {}",
"module.exports = Hello;",
"/** @constructor */ function Bar() {}",
"Bar.prototype.foobar = function() { alert('foobar'); };",
"module.exports = Bar;"),
LINE_JOINER.join(
"var Foobar = require('./i0');", "var show = new Foobar();", "show.foobar();")
},
new String[] {
LINE_JOINER.join(
"var module$i0",
"module$i0 = function () {};",
"module$i0 = function () {};",
"module$i0.prototype.foobar = function() { alert('foobar') };"),
LINE_JOINER.join(
"var Foobar = module$i0;", "var show = new module$i0();", "show.foobar();")
});
}
public void testMultipleExportAssignments2() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join(
"/** @constructor */ function Hello() {}",
"module.exports.foo = Hello;",
"/** @constructor */ function Bar() {} ",
"Bar.prototype.foobar = function() { alert('foobar'); };",
"module.exports.foo = Bar;"),
LINE_JOINER.join(
"var Foobar = require('./i0');", "var show = new Foobar.foo();", "show.foobar();")
},
new String[] {
LINE_JOINER.join(
"var module$i0 = {};",
"module$i0.foo = function (){};",
"module$i0.foo = function (){};",
"module$i0.foo.prototype.foobar = function(){ alert('foobar') };"),
LINE_JOINER.join(
"var Foobar = module$i0;", "var show = new module$i0.foo();", "show.foobar();")
});
}
public void testMultipleExportAssignments3() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join(
"/** @constructor */ function Hello() {}",
"module.exports.foo = Hello;",
"/** @constructor */ function Bar() {} ",
"Bar.prototype.foobar = function() { alert('foobar'); };",
"exports.foo = Bar;"),
LINE_JOINER.join(
"var Foobar = require('./i0');", "var show = new Foobar.foo();", "show.foobar();")
},
new String[] {
LINE_JOINER.join(
"var module$i0 = {};",
"module$i0.foo = function(){};",
"module$i0.foo = function(){};",
"module$i0.foo.prototype.foobar = function(){ alert('foobar') };"),
LINE_JOINER.join(
"var Foobar = module$i0;", "var show = new module$i0.foo();", "show.foobar();")
});
}
public void testCrossModuleSubclass1() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join("/** @constructor */ function Hello() {}", "module.exports = Hello;"),
LINE_JOINER.join(
"var Hello = require('./i0');",
"var util = {inherits: function (x, y){}};",
"/**\n",
" * @constructor\n",
" * @extends {Hello}\n",
" */\n",
"var SubHello = function () {};",
"util.inherits(SubHello, Hello);")
},
new String[] {
"var module$i0 = function (){};",
LINE_JOINER.join(
"var Hello = module$i0;",
"var util = { inherits : function(x,y) {} };",
"var SubHello = function() {};",
"util.inherits(SubHello, module$i0);")
});
}
public void testCrossModuleSubclass2() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join("/** @constructor */ function Hello() {}", "module.exports = Hello;"),
LINE_JOINER.join(
"var Hello = require('./i0');",
"var util = {inherits: function (x, y){}};",
"/**",
" * @constructor",
" * @extends {Hello}",
" */",
"function SubHello() {}",
"util.inherits(SubHello, Hello);")
},
new String[] {
"var module$i0 = function (){};",
LINE_JOINER.join(
"var Hello = module$i0;",
"var util = { inherits : function(x,y) {} };",
"function SubHello(){}",
"util.inherits(SubHello, module$i0);")
});
}
public void testCrossModuleSubclass3() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join("/** @constructor */ function Hello() {} ", "module.exports = Hello;"),
LINE_JOINER.join(
"var Hello = require('./i0');",
"var util = {inherits: function (x, y){}};",
"/**",
" * @constructor",
" * @extends {Hello}",
" */",
"function SubHello() { Hello.call(this); }",
"util.inherits(SubHello, Hello);")
},
new String[] {
"var module$i0 = function (){};",
LINE_JOINER.join(
"var Hello = module$i0;",
"var util = { inherits : function(x,y) {} };",
"function SubHello(){ module$i0.call(this); }",
"util.inherits(SubHello, module$i0);")
});
}
public void testCrossModuleSubclass4() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join(
"/** @constructor */ function Hello() {} ", "module.exports = {Hello: Hello};"),
LINE_JOINER.join(
"var i0 = require('./i0');",
"var util = {inherits: function (x, y) {}};",
"/**",
" * @constructor",
" * @extends {i0.Hello}",
" */",
"function SubHello() { i0.Hello.call(this); }",
"util.inherits(SubHello, i0.Hello);")
},
new String[] {
LINE_JOINER.join(
"/** @const */ var module$i0 = {};",
"module$i0.Hello = /** @constructor */ function (){};"),
LINE_JOINER.join(
"var i0 = module$i0;",
"var util = { inherits : function(x,y) {} };",
"function SubHello(){ module$i0.Hello.call(this); }",
"util.inherits(SubHello, module$i0.Hello);")
});
}
public void testCrossModuleSubclass5() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join("/** @constructor */ function Hello() {}", "module.exports = Hello;"),
LINE_JOINER.join(
"var Hello = require('./i0');",
"var util = {inherits: function (x, y){}};",
"/**",
" * @constructor",
" * @extends {./i0}",
" */",
"function SubHello() { Hello.call(this); }",
"util.inherits(SubHello, Hello);")
},
new String[] {
"var module$i0 = function (){};",
LINE_JOINER.join(
"var Hello = module$i0;",
"var util = { inherits : function(x,y) {} };",
"function SubHello(){ module$i0.call(this); }",
"util.inherits(SubHello, module$i0);")
});
}
public void testCrossModuleSubclass6() {
test(
createCompilerOptions(),
new String[] {
LINE_JOINER.join(
"/** @constructor */ function Hello() {}", "module.exports = {Hello: Hello};"),
LINE_JOINER.join(
"var i0 = require('./i0');",
"var util = {inherits: function (x, y){}};",
"/**",
" * @constructor",
" * @extends {./i0.Hello}",
" */",
"function SubHello() { i0.Hello.call(this); }",
"util.inherits(SubHello, i0.Hello);")
},
new String[] {
LINE_JOINER.join("var module$i0 = {};", "module$i0.Hello = function (){};"),
LINE_JOINER.join(
"var i0 = module$i0;",
"var util = {inherits:function(x,y){}};",
"function SubHello(){ module$i0.Hello.call(this); }",
"util.inherits(SubHello, module$i0.Hello);")
});
}
@Override
protected CompilerOptions createCompilerOptions() {
CompilerOptions options = new CompilerOptions();
options.setCodingConvention(new GoogleCodingConvention());
WarningLevel.VERBOSE.setOptionsForWarningLevel(options);
options.setProcessCommonJSModules(true);
options.setClosurePass(true);
return options;
}
}