diff --git a/Objective-J/Preprocessor.js b/Objective-J/Preprocessor.js index 88dfda08e..5b14dac32 100644 --- a/Objective-J/Preprocessor.js +++ b/Objective-J/Preprocessor.js @@ -681,7 +681,7 @@ Preprocessor.prototype.method = function(/*Lexer*/ tokens, ivar_names) parameters[parameters.length] = token; if (token in ivar_names) - throw new SyntaxError(this.error_message("*** Method ( "+selector+" ) uses a parameter name that is already in use ( "+token+" )")); + CPLog.warn(this.error_message("*** Warning: Method ( "+selector+" ) uses a parameter name that is already in use ( "+token+" )")); } else if (token == TOKEN_OPEN_PARENTHESIS) { diff --git a/Tests/Objective-J/Preprocessor/BehaviorTests/InheritanceTest.j b/Tests/Objective-J/Preprocessor/BehaviorTests/InheritanceTest.j new file mode 100644 index 000000000..5fcd7b5f4 --- /dev/null +++ b/Tests/Objective-J/Preprocessor/BehaviorTests/InheritanceTest.j @@ -0,0 +1,131 @@ +@import + +@implementation ParentClass : CPObject +{ + id ivar; +} + +- (CPString)classNameString +{ + return @"ParentClass"; +} + +@end + +@implementation ChildClass : ParentClass +{ +} + +- (id)ivar +{ + return ivar; +} + +- (void)setIvar:(id)newValue +{ + ivar = newValue; +} + +- (CPString)classNameString +{ + return @"ChildClass"; +} + +- (CPString)parentClassNameString +{ + return [super classNameString]; +} + +@end + +@implementation GrandChildClass : ChildClass +{ +} + +- (CPString)classNameString +{ + return @"GrandChildClass"; +} + +- (CPString)parentClassNameString +{ + return [super classNameString]; +} + +- (CPString)grandParentClassNameString +{ + return [super parentClassNameString]; +} + +@end + +@implementation InheritanceTest : OJTestCase +{ + ParentClass parentClass; + ChildClass childClass; + GrandChildClass grandChildClass; +} + +- (void)setUp +{ + parentClass = [[ParentClass alloc] init]; + childClass = [[ChildClass alloc] init]; + grandChildClass = [[GrandChildClass alloc] init]; +} + +- (void)testIvarInheritance +{ + [self assert:nil equals:parentClass.ivar]; + [self assert:nil equals:childClass.ivar]; + [self assert:nil equals:grandChildClass.ivar]; + + parentClass.ivar = 1; + childClass.ivar = 2; + grandChildClass.ivar = 3; + + [self assert:1 equals:parentClass.ivar]; + [self assert:2 equals:childClass.ivar]; + [self assert:3 equals:grandChildClass.ivar]; +} + +- (void)testIvarIndependence +{ + parentClass.ivar = 1; + [self assert:1 equals:parentClass.ivar]; + [self assert:nil equals:childClass.ivar]; + [self assert:nil equals:grandChildClass.ivar]; + + childClass.ivar = 2; + [self assert:1 equals:parentClass.ivar]; + [self assert:2 equals:childClass.ivar]; + [self assert:nil equals:grandChildClass.ivar]; + + grandChildClass.ivar = 3; + [self assert:1 equals:parentClass.ivar]; + [self assert:2 equals:childClass.ivar]; + [self assert:3 equals:grandChildClass.ivar]; +} + +- (void)testMethodInheritance +{ + [self assertThrows:function() + { + [parentClass setIvar:5]; + }]; + [childClass setIvar:5]; + [grandChildClass setIvar:10]; + [self assert:nil equals:parentClass.ivar]; + [self assert:5 equals:childClass.ivar]; + [self assert:10 equals:grandChildClass.ivar]; +} + +- (void)testSuper +{ + [self assert:@"ParentClass" equals:[parentClass classNameString]]; + [self assert:@"ParentClass" equals:[childClass parentClassNameString]]; + [self assert:@"ParentClass" equals:[grandChildClass grandParentClassNameString]]; +} + +@end + + diff --git a/Tests/Objective-J/Preprocessor/BehaviorTests/IvarTest.j b/Tests/Objective-J/Preprocessor/BehaviorTests/IvarTest.j new file mode 100644 index 000000000..d0c38aad9 --- /dev/null +++ b/Tests/Objective-J/Preprocessor/BehaviorTests/IvarTest.j @@ -0,0 +1,117 @@ +@import + +@implementation IvarTestClass : CPObject +{ + id ivar1 @accessors; + var ivar2 @accessors(readonly); + CPNumber ivar3; +} + +- (void)setIvar1UsingEval:(id)value +{ + eval(@"var ivar1 = " + value); +} + +- (void)doNothingToIvar1UsingEval:(id)value +{ + (function() + { + eval(@"var ivar1 = " + value); + })(); +} + +- (void)setIvar1DespiteAWithStatement:(id)value +{ + with({}) + { + ivar1 = value; + } +} + +- (void)doNothingToIvar1BecauseOfWithStatement:(id)value +{ + with({'ivar1':null}) + { + ivar1 = value; + } +} + +- (void)setIvar1UsingAShadowingLocalVariable:(id)ivar1 +{ + self.ivar1 = ivar1; +} + +@end + +@implementation IvarTest : OJTestCase +{ + IvarTestClass testClass; +} + +- (void)setUp +{ + testClass = [[IvarTestClass alloc] init]; +} + +- (void)testDirectAccess +{ + [self assert:nil equals:testClass.ivar1]; + testClass.ivar1 = 5; + [self assert:5 equals:testClass.ivar1]; +} + +- (void)testWithStatementInMethod +{ + [self assert:nil equals:testClass.ivar1]; + [testClass setIvar1DespiteAWithStatement:5]; + [self assert:5 equals:testClass.ivar1]; + [testClass doNothingToIvar1BecauseOfWithStatement:10]; + [self assert:5 equals:testClass.ivar1]; +} + +- (void)testEvalInMethod +{ + [self assert:nil equals:testClass.ivar1]; + [testClass setIvar1UsingEval:5]; + [self assert:5 equals:testClass.ivar1]; + [testClass doNothingToIvar1UsingEval:10]; + [self assert:5 equals:testClass.ivar1]; +} + +- (void)testIvarShadowing +{ + [self assert:nil equals:testClass.ivar1]; + [testClass setIvar1UsingAShadowingLocalVariable:5]; + [self assert:5 equals:testClass.ivar1]; +} + +- (void)testAccessorGeneration +{ + [self assert:nil equals:[testClass ivar1]]; + [testClass setIvar1:10]; + [self assert:10 equals:[testClass ivar1]]; + [self assert:10 equals:testClass.ivar1]; + + [self assert:nil equals:[testClass ivar2]]; + testClass.ivar2 = 5; + [self assert:5 equals:[testClass ivar2]]; + [self assert:5 equals:testClass.ivar2]; + [self assertThrows:function() + { + [testClass setIvar2:6]; + }]; + [self assert:5 equals:[testClass ivar2]]; + + [self assert:nil equals:testClass.ivar3]; + [self assertThrows:function() + { + [testClass ivar3]; + }]; + [self assertThrows:function() + { + [testClass setIvar3:20]; + }]; + [self assert:nil equals:testClass.ivar3]; +} + +@end diff --git a/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j b/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j new file mode 100644 index 000000000..e1e9a6df9 --- /dev/null +++ b/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j @@ -0,0 +1,65 @@ +@import + +@implementation MathClass : CPObject +{ +} + +- (CPNumber)five +{ + return 5; +} + +- (CPNumber)sqrt:(CPNumber)operand +{ + return Math.sqrt(operand); +} + +- (CPNumber)multiply:(CPNumber)firstOperand with:(CPNumber)secondOperand +{ + return firstOperand * secondOperand; +} + +- (CPNumber)multiply:(CPNumber)operand, ... +{ + var product; + + for (var i = 2, ii = arguments.length; i < ii; ++i) + product = product ? product * arguments[i] : arguments[i]; + + return product; +} + +@end + +@implementation MethodTest : OJTestCase +{ + MathClass testClass; +} + +- (void)setUp +{ + testClass = [[MathClass alloc] init]; +} + +- (void)testNoParameters +{ + [self assert:5 equals:[testClass five]]; +} + +- (void)testOneParameter +{ + [self assert:2 equals:[testClass sqrt:4]]; +} + +- (void)testTwoParameters +{ + [self assert:6 equals:[testClass multiply:2 with:3]]; +} + +- (void)testVarArgs +{ + [self assert:30 equals:[testClass multiply:2,3,5]]; + [self assert:2310 equals:[testClass multiply:2,3,5,7,11]]; +} + +@end diff --git a/Tests/Objective-J/Preprocessor/Class/root-class-multiple-ivars.j b/Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-multiple-ivars.j similarity index 100% rename from Tests/Objective-J/Preprocessor/Class/root-class-multiple-ivars.j rename to Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-multiple-ivars.j diff --git a/Tests/Objective-J/Preprocessor/Class/root-class-multiple-ivars.js b/Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-multiple-ivars.js similarity index 100% rename from Tests/Objective-J/Preprocessor/Class/root-class-multiple-ivars.js rename to Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-multiple-ivars.js diff --git a/Tests/Objective-J/Preprocessor/Class/root-class-one-ivar.j b/Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-one-ivar.j similarity index 100% rename from Tests/Objective-J/Preprocessor/Class/root-class-one-ivar.j rename to Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-one-ivar.j diff --git a/Tests/Objective-J/Preprocessor/Class/root-class-one-ivar.js b/Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-one-ivar.js similarity index 100% rename from Tests/Objective-J/Preprocessor/Class/root-class-one-ivar.js rename to Tests/Objective-J/Preprocessor/OutputTests/Class/root-class-one-ivar.js diff --git a/Tests/Objective-J/Preprocessor/Class/root-class.j b/Tests/Objective-J/Preprocessor/OutputTests/Class/root-class.j similarity index 100% rename from Tests/Objective-J/Preprocessor/Class/root-class.j rename to Tests/Objective-J/Preprocessor/OutputTests/Class/root-class.j diff --git a/Tests/Objective-J/Preprocessor/Class/root-class.js b/Tests/Objective-J/Preprocessor/OutputTests/Class/root-class.js similarity index 100% rename from Tests/Objective-J/Preprocessor/Class/root-class.js rename to Tests/Objective-J/Preprocessor/OutputTests/Class/root-class.js diff --git a/Tests/Objective-J/Preprocessor/Messages/multiple-parameters.j b/Tests/Objective-J/Preprocessor/OutputTests/Messages/multiple-parameters.j similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/multiple-parameters.j rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/multiple-parameters.j diff --git a/Tests/Objective-J/Preprocessor/Messages/multiple-parameters.js b/Tests/Objective-J/Preprocessor/OutputTests/Messages/multiple-parameters.js similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/multiple-parameters.js rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/multiple-parameters.js diff --git a/Tests/Objective-J/Preprocessor/Messages/no-parameters.j b/Tests/Objective-J/Preprocessor/OutputTests/Messages/no-parameters.j similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/no-parameters.j rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/no-parameters.j diff --git a/Tests/Objective-J/Preprocessor/Messages/no-parameters.js b/Tests/Objective-J/Preprocessor/OutputTests/Messages/no-parameters.js similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/no-parameters.js rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/no-parameters.js diff --git a/Tests/Objective-J/Preprocessor/Messages/one-parameter.j b/Tests/Objective-J/Preprocessor/OutputTests/Messages/one-parameter.j similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/one-parameter.j rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/one-parameter.j diff --git a/Tests/Objective-J/Preprocessor/Messages/one-parameter.js b/Tests/Objective-J/Preprocessor/OutputTests/Messages/one-parameter.js similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/one-parameter.js rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/one-parameter.js diff --git a/Tests/Objective-J/Preprocessor/Messages/ternary-operator-argument.j b/Tests/Objective-J/Preprocessor/OutputTests/Messages/ternary-operator-argument.j similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/ternary-operator-argument.j rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/ternary-operator-argument.j diff --git a/Tests/Objective-J/Preprocessor/Messages/ternary-operator-argument.js b/Tests/Objective-J/Preprocessor/OutputTests/Messages/ternary-operator-argument.js similarity index 100% rename from Tests/Objective-J/Preprocessor/Messages/ternary-operator-argument.js rename to Tests/Objective-J/Preprocessor/OutputTests/Messages/ternary-operator-argument.js diff --git a/Tests/Objective-J/Preprocessor/OutputTests/Misc/regex-simple-char-classes.j b/Tests/Objective-J/Preprocessor/OutputTests/Misc/regex-simple-char-classes.j new file mode 100644 index 000000000..dbc548b70 --- /dev/null +++ b/Tests/Objective-J/Preprocessor/OutputTests/Misc/regex-simple-char-classes.j @@ -0,0 +1,10 @@ +/[\{]/; +/[\}]/; +/[@]/; +/[\[]/; +/[\]]/; +/[#]/; +/[\(]/; +/[\)]/; +/(\[)/; +/(\])/; diff --git a/Tests/Objective-J/Preprocessor/OutputTests/Misc/regex-simple-char-classes.js b/Tests/Objective-J/Preprocessor/OutputTests/Misc/regex-simple-char-classes.js new file mode 100644 index 000000000..dbc548b70 --- /dev/null +++ b/Tests/Objective-J/Preprocessor/OutputTests/Misc/regex-simple-char-classes.js @@ -0,0 +1,10 @@ +/[\{]/; +/[\}]/; +/[@]/; +/[\[]/; +/[\]]/; +/[#]/; +/[\(]/; +/[\)]/; +/(\[)/; +/(\])/; diff --git a/Tests/Objective-J/Preprocessor/OutputTests/OutputTest.j b/Tests/Objective-J/Preprocessor/OutputTests/OutputTest.j new file mode 100644 index 000000000..f9048e927 --- /dev/null +++ b/Tests/Objective-J/Preprocessor/OutputTests/OutputTest.j @@ -0,0 +1,55 @@ + +var FILE = require("file"), + compressor = require("minify/shrinksafe"); + +var FILENAMES = [ + "Class/root-class", + "Class/root-class-one-ivar", + "Class/root-class-multiple-ivars", + + "Messages/no-parameters", + "Messages/one-parameter", + "Messages/multiple-parameters", + "Messages/ternary-operator-argument", + + "Misc/regex-simple-char-classes" + ]; + +@implementation OutputTest : OJTestCase +{ +} + ++ (void)initialize +{ + var index = 0, + count = FILENAMES.length; + + for (; index < count; ++index) + { + (function () + { + var filename = FILENAMES[index], + testSelector = sel_getUid("test" + FILENAMES[index]); + + class_addMethod(self, testSelector, function(self, _cmd) + { + var filePath = FILE.join(FILE.dirname(module.path), filename + ".j"), + unpreprocessed = FILE.read(filePath, { charset:"UTF-8" }), + preprocessed, + correct = FILE.read(FILE.join(FILE.dirname(module.path), filename + ".js")); + + [self assertNoThrow:function() { + preprocessed = ObjectiveJ.preprocess(unpreprocessed).code(), + preprocessed = compressor.compress(preprocessed, { charset : "UTF-8", useServer : true }); + correct = compressor.compress(correct, { charset : "UTF-8", useServer : true }); + }]; + + [self assert:preprocessed equals:correct]; + }); + })(); + } +} + +@end + +[OutputTest alloc]; diff --git a/Tests/Objective-J/Preprocessor/PreprocessorTest.j b/Tests/Objective-J/Preprocessor/PreprocessorTest.j deleted file mode 100644 index 946ec50c8..000000000 --- a/Tests/Objective-J/Preprocessor/PreprocessorTest.j +++ /dev/null @@ -1,47 +0,0 @@ - -var FILE = require("file"), - compressor = require("minify/shrinksafe"); - -var FILENAMES = [ - "Class/root-class", - "Class/root-class-one-ivar", - "Class/root-class-multiple-ivars", - - "Messages/no-parameter", - "Messages/one-parameter", - "Messages/multiple-parameters", - "Messages/ternary-operator-argument" - ]; - -@implementation PreprocessorTest : OJTestCase -{ -} - -+ (void)initialize -{ - var index = 0, - count = FILENAMES.length; - - for (; index < count; ++index) - { - var filename = FILENAMES[index], - testSelector = sel_getUid("test" + FILENAMES[index]) - - class_addMethod(self, testSelector, function(self, _cmd) - { - var filePath = FILE.join(FILE.dirname(module.path), filename + ".j"), - unpreprocessed = FILE.read(filePath, { charset:"UTF-8" }); - preprocessed = ObjectiveJ.preprocess(unpreprocessed).code(), - correct = FILE.read(FILE.join(FILE.dirname(module.path), filename + ".js")); - - preprocessed = compressor.compress(preprocessed, { charset : "UTF-8", useServer : true }); - correct = compressor.compress(correct, { charset : "UTF-8", useServer : true }); - - [self assert:preprocessed equals:correct]; - }); - } -} - -@end - -[PreprocessorTest alloc]; \ No newline at end of file