From 1733338f5905da4ba10ffc3cbc091e1ef0401c1b Mon Sep 17 00:00:00 2001 From: Adam Fedor Date: Mon, 6 Jul 2015 15:44:46 -0600 Subject: [PATCH 1/3] Add some GC tests --- Cocoa Script.xcodeproj/project.pbxproj | 29 +++ CocoaScriptTests/GarbageCollectionTests.m | 206 ++++++++++++++++++ CocoaScriptTests/Resources/CoreGraphics.js | 42 ++++ CocoaScriptTests/Resources/GarbageCollect2.js | 17 ++ .../Resources/JSMemoryAllocation.js | 31 +++ .../Resources/MemoryAllocation.js | 32 +++ 6 files changed, 357 insertions(+) create mode 100644 CocoaScriptTests/GarbageCollectionTests.m create mode 100644 CocoaScriptTests/Resources/CoreGraphics.js create mode 100644 CocoaScriptTests/Resources/GarbageCollect2.js create mode 100644 CocoaScriptTests/Resources/JSMemoryAllocation.js create mode 100644 CocoaScriptTests/Resources/MemoryAllocation.js diff --git a/Cocoa Script.xcodeproj/project.pbxproj b/Cocoa Script.xcodeproj/project.pbxproj index 39399bc..336f10b 100644 --- a/Cocoa Script.xcodeproj/project.pbxproj +++ b/Cocoa Script.xcodeproj/project.pbxproj @@ -10,6 +10,11 @@ 384830E21832D48500B34168 /* COSTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 384830E01832D48500B34168 /* COSTarget.h */; }; 384830E31832D48500B34168 /* COSTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = 384830E11832D48500B34168 /* COSTarget.m */; }; 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; }; + 9F5068D81B4B20B400A2218F /* CoreGraphics.js in Resources */ = {isa = PBXBuildFile; fileRef = 9F5068D41B4B20B400A2218F /* CoreGraphics.js */; }; + 9F5068D91B4B20B400A2218F /* GarbageCollect2.js in Resources */ = {isa = PBXBuildFile; fileRef = 9F5068D51B4B20B400A2218F /* GarbageCollect2.js */; }; + 9F5068DA1B4B20B400A2218F /* JSMemoryAllocation.js in Resources */ = {isa = PBXBuildFile; fileRef = 9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */; }; + 9F5068DB1B4B20B400A2218F /* MemoryAllocation.js in Resources */ = {isa = PBXBuildFile; fileRef = 9F5068D71B4B20B400A2218F /* MemoryAllocation.js */; }; + 9F5068DD1B4B20BB00A2218F /* GarbageCollectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */; }; 9FC343CD1AF7D2FE00B53759 /* CocoaScript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC41431A0F25254200E46669 /* CocoaScript.framework */; }; 9FC343D51AF7D32B00B53759 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9FC343D31AF7D32B00B53759 /* Model.xcdatamodeld */; }; 9FC343D71AF7D33300B53759 /* CSPropertyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FC343D61AF7D33300B53759 /* CSPropertyTests.m */; }; @@ -402,6 +407,11 @@ 384830E01832D48500B34168 /* COSTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = COSTarget.h; path = src/framework/COSTarget.h; sourceTree = ""; }; 384830E11832D48500B34168 /* COSTarget.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = COSTarget.m; path = src/framework/COSTarget.m; sourceTree = ""; }; 8D15AC370486D014006FF6A4 /* Cocoa Script Editor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cocoa Script Editor.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9F5068D41B4B20B400A2218F /* CoreGraphics.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = CoreGraphics.js; sourceTree = ""; }; + 9F5068D51B4B20B400A2218F /* GarbageCollect2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = GarbageCollect2.js; sourceTree = ""; }; + 9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = JSMemoryAllocation.js; sourceTree = ""; }; + 9F5068D71B4B20B400A2218F /* MemoryAllocation.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = MemoryAllocation.js; sourceTree = ""; }; + 9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GarbageCollectionTests.m; sourceTree = ""; }; 9FC343C71AF7D2FE00B53759 /* CocoaScriptTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CocoaScriptTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 9FC343CA1AF7D2FE00B53759 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9FC343D41AF7D32B00B53759 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = ""; }; @@ -806,10 +816,23 @@ name = Frameworks; sourceTree = ""; }; + 9F5068D31B4B20B400A2218F /* Resources */ = { + isa = PBXGroup; + children = ( + 9F5068D41B4B20B400A2218F /* CoreGraphics.js */, + 9F5068D51B4B20B400A2218F /* GarbageCollect2.js */, + 9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */, + 9F5068D71B4B20B400A2218F /* MemoryAllocation.js */, + ); + path = Resources; + sourceTree = ""; + }; 9FC343C81AF7D2FE00B53759 /* CocoaScriptTests */ = { isa = PBXGroup; children = ( 9FC343D61AF7D33300B53759 /* CSPropertyTests.m */, + 9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */, + 9F5068D31B4B20B400A2218F /* Resources */, 9FC343C91AF7D2FE00B53759 /* Supporting Files */, ); path = CocoaScriptTests; @@ -1452,6 +1475,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9F5068D91B4B20B400A2218F /* GarbageCollect2.js in Resources */, + 9F5068DB1B4B20B400A2218F /* MemoryAllocation.js in Resources */, + 9F5068D81B4B20B400A2218F /* CoreGraphics.js in Resources */, + 9F5068DA1B4B20B400A2218F /* JSMemoryAllocation.js in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1485,6 +1512,7 @@ buildActionMask = 2147483647; files = ( 9FC343D71AF7D33300B53759 /* CSPropertyTests.m in Sources */, + 9F5068DD1B4B20BB00A2218F /* GarbageCollectionTests.m in Sources */, 9FC343D51AF7D32B00B53759 /* Model.xcdatamodeld in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2002,6 +2030,7 @@ 9FC343D21AF7D2FE00B53759 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "Cocoa Script Editor" */ = { isa = XCConfigurationList; diff --git a/CocoaScriptTests/GarbageCollectionTests.m b/CocoaScriptTests/GarbageCollectionTests.m new file mode 100644 index 0000000..97edd60 --- /dev/null +++ b/CocoaScriptTests/GarbageCollectionTests.m @@ -0,0 +1,206 @@ +// +// GarbageCollectionTests.m +// Cocoa Script +// +// Created by Adam Fedor on 7/6/15. +// +// + +#import +#import +#import "COScript.h" + +@interface GarbageCollectionTests : XCTestCase + +@end + +@implementation GarbageCollectionTests +{ + COScript *jsContext; + NSURL *testScriptURL; +} + +- (void)setUp { + [super setUp]; + testScriptURL = [[NSBundle bundleForClass: [self class]] resourceURL]; + jsContext = [[COScript alloc] init]; +} + +- (void)tearDown { + [super tearDown]; +} + +#pragma mark Simple Scripts +- (void)testCallFunctionWithName_WithSimpleAdd +{ + [jsContext executeString: @"function add() { return 1 + 1}"]; + + id result = [jsContext executeString: @"add()"]; + XCTAssertTrue([result isEqualTo: @(2)], @"Adding doesnt work"); +} + +- (void)testCallFunctionWithName_WithSimpleAddMultipleTimes +{ + [jsContext executeString: @"function add() { return 1 + 1}"]; + + id result; + for (NSInteger i = 0; i < 1000; i++) { + result = [jsContext executeString: @"add()"]; + } + XCTAssertTrue([result isEqualTo: @(2)], @"Adding multiple doesnt work"); +} + +- (void)testCallFunctionWithName_WithObjectFunction +{ + [jsContext executeString: @"function myfunc() { var dict = NSMutableDictionary.dictionary(); \ + dict.setObject_forKey_(\"foobar\", \"string\"); return 2;}"]; + + id result = [jsContext executeString: @"myfunc()"]; + XCTAssertTrue([result isEqualTo: @(2)], @"Myfunc doesnt work"); +} + +- (void)testCallFunctionWithName_WithObjectFunctionMultipleTimes +{ + [jsContext executeString: @"function myfunc() { var dict = NSMutableDictionary.dictionary(); \ + dict.setObject_forKey_(\"foobar\", \"string\"); return 2;}"]; + + id result; + for (NSInteger i = 0; i < 1000; i++) { + result = [jsContext executeString: @"myfunc()"]; + } + XCTAssertTrue([result isEqualTo: @(2)], @"Myfunc multiple doesnt work"); +} + +- (void)testCallFunctionWithName_WithIdenticalProperties_CanChangeEachPropertySeperately +{ + [jsContext executeString: @"function myfunc() { \ + var dict1 = NSMutableDictionary.dictionary(); \ + var dict2 = NSMutableDictionary.dictionary(); \ + dict1.setObject_forKey_(\"foobar\", \"string\"); \ + print(\"dict1 is \" + dict1); \ + print(\"dict2 is \" + dict2); \ + return dict2.count();}"]; + + id result = [jsContext executeString: @"myfunc()"]; + XCTAssertTrue([result isEqualTo: @(0)], @"Setting mutable dictionary doesnt work"); +} + +#pragma mark Stored Scripts + +- (void)testUsingCoreGraphicsScript_ShouldRun { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"CoreGraphics.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + + [jsContext executeString:testScript]; + + NSArray *result = [jsContext executeString:@"main()"]; + XCTAssertTrue([result[0] boolValue], @"%@", result[1]); + result = nil; +} + +#pragma mark Memory Allocation +- (void)test_10_UsingMemoryAllocationScript_ShouldRun { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"JSMemoryAllocation.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + + [jsContext executeString:testScript]; + + NSArray *result = [jsContext callFunctionNamed: @"main" withArguments: @[@(10)]]; + XCTAssertTrue([result[0] boolValue], @"%@", result[1]); +} + +- (void)test_11_UsingMemoryAllocationScript_ShouldRun { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"MemoryAllocation.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + + [jsContext executeString:testScript]; + + NSArray *result = [jsContext callFunctionNamed:@"main" withArguments: @[@(10)]]; + XCTAssertTrue([result[0] boolValue], @"%@", result[1]); +} + +- (void)test_12_UsingJSMemoryAllocationScript_WithMoreIterations_ShouldRunFast { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"JSMemoryAllocation.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + + [jsContext executeString:testScript]; + + __block NSArray *result; + [self measureBlock:^{ + result = [jsContext callFunctionNamed:@"main" withArguments: @[@(5000)]]; + }]; + XCTAssertTrue([result[0] boolValue], @"%@", result[1]); +} + +- (void)test_13_UsingMemoryAllocationScript_WithMoreIterations_ShouldRunFast { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"MemoryAllocation.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + + [jsContext executeString:testScript]; + + __block NSArray *result; + [self measureBlock:^{ + result = [jsContext callFunctionNamed:@"main" withArguments: @[@(500)]]; + }]; + XCTAssertTrue([result[0] boolValue], @"%@", result[1]); +} + +#pragma mark Garbage Collection +/* Takes ~.7 sec on a 2011 Mini */ +- (void)test_14_UsingJSMemoryAllocationScript_WithHugeNumberOfIterations_ShouldNotCrash { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"JSMemoryAllocation.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + + [jsContext executeString:testScript]; + + NSArray *result; + result = [jsContext callFunctionNamed:@"main" withArguments: @[@(100000)]]; + XCTAssertTrue([result[0] boolValue], @"%@", result[1]); +} + +/* Unfortunately this will just crash if it doesn't work. Takes ~70 sec on a 2011 Mini */ +- (void)test_15_UsingMemoryAllocationScript_WithHugeNumberOfIterations_ShouldNotCrash { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"MemoryAllocation.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + + [jsContext executeString:testScript]; + + NSArray *result; + result = [jsContext callFunctionNamed:@"main" withArguments: @[@(100000)]]; + XCTAssertTrue([result[0] boolValue], @"%@", result[1]); +} + +/* Unfortunately this will just crash if it doesn't work. Takes ~10 sec on a 2011 Mini */ +- (void)test_16_UsingGarbageCollect2Script_WithHugeNumberOfIterations_ShouldNotCrash { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"GarbageCollect2.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + [jsContext executeString: testScript]; + + XCTAssertTrue(1, @"GarbageCollect2 Test did not run"); +} + +@end diff --git a/CocoaScriptTests/Resources/CoreGraphics.js b/CocoaScriptTests/Resources/CoreGraphics.js new file mode 100644 index 0000000..6e73d7f --- /dev/null +++ b/CocoaScriptTests/Resources/CoreGraphics.js @@ -0,0 +1,42 @@ +// +// CoreGraphics.js +// UnitTests +// +// Created by Logan Collins on 7/25/12. +// Copyright (c) 2012 Sunflower Softworks. All rights reserved. +// + +function main() { + var fm = NSFileManager.alloc().init(); + + var url = NSURL.fileURLWithPath_("/tmp/foo.pdf"); + fm.removeItemAtURL_error_(url, null); + + var rect = CGRectMake(0.0, 0.0, 100.0, 100.0); + var rectPtr = MOPointer.alloc().initWithValue_(rect); + var c = CGPDFContextCreateWithURL(url, rect, null); + + CGPDFContextBeginPage(c, null); + + var redColor = CGColorCreateGenericRGB(1.0, 0.0, 0.0, 1.0); + CGContextSetFillColorWithColor(c, redColor); + CGContextFillRect(c, NSMakeRect(0.0, 0.0, 50.0, 50.0)); + CGColorRelease(redColor); + + var greenColor = CGColorCreateGenericRGB(0.0, 1.0, 0.0, 1.0); + CGContextSetFillColorWithColor(c, redColor); + CGContextFillRect(c, NSMakeRect(50.0, 0.0, 25.0, 50.0)); + CGColorRelease(greenColor); + + var blueColor = CGColorCreateGenericRGB(0.0, 0.0, 1.0, 1.0); + CGContextSetFillColorWithColor(c, redColor); + CGContextFillRect(c, NSMakeRect(25.0, 25.0, 25.0, 25.0)); + CGColorRelease(blueColor); + + CGPDFContextEndPage(c); + + CGPDFContextClose(c); + CGContextRelease(c); + + return [true, null]; +} diff --git a/CocoaScriptTests/Resources/GarbageCollect2.js b/CocoaScriptTests/Resources/GarbageCollect2.js new file mode 100644 index 0000000..7b392aa --- /dev/null +++ b/CocoaScriptTests/Resources/GarbageCollect2.js @@ -0,0 +1,17 @@ + + +function createStory(j) { + var role = NSString.stringWithString("CFBundleTypeRole"); + var ddict = NSMutableDictionary.dictionary(); + var dict = {}; + ddict["role"] = role; + dict["role"] = ddict["role"]; + ddict["role"] = dict["role"]; + role = ddict["role"]; + print("role " + j + " length " + role.length); +} + +for (var j = 0; j < 10000; j++) { + //print("==== LOOP " + j + " ====="); + createStory(j); +} diff --git a/CocoaScriptTests/Resources/JSMemoryAllocation.js b/CocoaScriptTests/Resources/JSMemoryAllocation.js new file mode 100644 index 0000000..51d221d --- /dev/null +++ b/CocoaScriptTests/Resources/JSMemoryAllocation.js @@ -0,0 +1,31 @@ +// +// MemoryAllocation.js +// UnitTests +// +// Created by Logan Collins on 7/25/12. +// Copyright (c) 2012 Sunflower Softworks. All rights reserved. +// + +function main(iterations) { + var array = []; + for (var i=0; i Date: Mon, 6 Jul 2015 16:22:57 -0600 Subject: [PATCH 2/3] More GC tests --- Cocoa Script.xcodeproj/project.pbxproj | 4 ++++ CocoaScriptTests/GarbageCollectionTests.m | 11 ++++++++++ CocoaScriptTests/Resources/loadPlist.js | 25 +++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 CocoaScriptTests/Resources/loadPlist.js diff --git a/Cocoa Script.xcodeproj/project.pbxproj b/Cocoa Script.xcodeproj/project.pbxproj index 336f10b..d8c9f47 100644 --- a/Cocoa Script.xcodeproj/project.pbxproj +++ b/Cocoa Script.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 9F5068DA1B4B20B400A2218F /* JSMemoryAllocation.js in Resources */ = {isa = PBXBuildFile; fileRef = 9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */; }; 9F5068DB1B4B20B400A2218F /* MemoryAllocation.js in Resources */ = {isa = PBXBuildFile; fileRef = 9F5068D71B4B20B400A2218F /* MemoryAllocation.js */; }; 9F5068DD1B4B20BB00A2218F /* GarbageCollectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */; }; + 9F5068DF1B4B36BA00A2218F /* loadPlist.js in Resources */ = {isa = PBXBuildFile; fileRef = 9F5068DE1B4B36BA00A2218F /* loadPlist.js */; }; 9FC343CD1AF7D2FE00B53759 /* CocoaScript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC41431A0F25254200E46669 /* CocoaScript.framework */; }; 9FC343D51AF7D32B00B53759 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9FC343D31AF7D32B00B53759 /* Model.xcdatamodeld */; }; 9FC343D71AF7D33300B53759 /* CSPropertyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FC343D61AF7D33300B53759 /* CSPropertyTests.m */; }; @@ -412,6 +413,7 @@ 9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = JSMemoryAllocation.js; sourceTree = ""; }; 9F5068D71B4B20B400A2218F /* MemoryAllocation.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = MemoryAllocation.js; sourceTree = ""; }; 9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GarbageCollectionTests.m; sourceTree = ""; }; + 9F5068DE1B4B36BA00A2218F /* loadPlist.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = loadPlist.js; sourceTree = ""; }; 9FC343C71AF7D2FE00B53759 /* CocoaScriptTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CocoaScriptTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 9FC343CA1AF7D2FE00B53759 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9FC343D41AF7D32B00B53759 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = ""; }; @@ -819,6 +821,7 @@ 9F5068D31B4B20B400A2218F /* Resources */ = { isa = PBXGroup; children = ( + 9F5068DE1B4B36BA00A2218F /* loadPlist.js */, 9F5068D41B4B20B400A2218F /* CoreGraphics.js */, 9F5068D51B4B20B400A2218F /* GarbageCollect2.js */, 9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */, @@ -1479,6 +1482,7 @@ 9F5068DB1B4B20B400A2218F /* MemoryAllocation.js in Resources */, 9F5068D81B4B20B400A2218F /* CoreGraphics.js in Resources */, 9F5068DA1B4B20B400A2218F /* JSMemoryAllocation.js in Resources */, + 9F5068DF1B4B36BA00A2218F /* loadPlist.js in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/CocoaScriptTests/GarbageCollectionTests.m b/CocoaScriptTests/GarbageCollectionTests.m index 97edd60..e14bfc0 100644 --- a/CocoaScriptTests/GarbageCollectionTests.m +++ b/CocoaScriptTests/GarbageCollectionTests.m @@ -203,4 +203,15 @@ - (void)test_16_UsingGarbageCollect2Script_WithHugeNumberOfIterations_ShouldNotC XCTAssertTrue(1, @"GarbageCollect2 Test did not run"); } +/* Unfortunately this will just crash if it doesn't work. */ +- (void)test_17_UsingLoadPlist_WithHugeNumberOfIterations_ShouldNotCrash { + NSURL *URL = [testScriptURL URLByAppendingPathComponent: @"loadPlist.js"]; + NSError *error = nil; + NSString *testScript = [NSString stringWithContentsOfURL:URL usedEncoding:NULL error:&error]; + + XCTAssertNotNil(testScript, @"Error loading test script: %@", error); + [jsContext executeString: testScript]; + + XCTAssertTrue(1, @"loadPlist Test did not run"); +} @end diff --git a/CocoaScriptTests/Resources/loadPlist.js b/CocoaScriptTests/Resources/loadPlist.js new file mode 100644 index 0000000..e68c869 --- /dev/null +++ b/CocoaScriptTests/Resources/loadPlist.js @@ -0,0 +1,25 @@ +// +print("JAVASCRIPT: Starting loadStoriesList"); + +var debug = 1; +var toClass = {}.toString; + +function createStory(item, i) { + var name = item["CFBundleTypeName"]; + var role = item["CFBundleTypeRole"]; + print("Looking at strings"); + print("name class " + toClass(name) + " length " + name.length()); + print("role class " + role.class + " length " + role.length()); +} + +for (var j = 0; j < 100; j++) { + print("==== LOOP " + j + " ====="); + var itemDictPath = "/Applications/Xcode.app/Contents/Info.plist"; + var itemDict = NSDictionary.dictionaryWithContentsOfFile(itemDictPath); + var itemList = itemDict["CFBundleDocumentTypes"]; + for (var i = 0; i < itemList.length; i++) { + createStory(itemList[i], i); + } +} + +print("JAVASCRIPT: Done loadStoriesList"); From f2fceb0859043712124f0578ba82bc00c01129a5 Mon Sep 17 00:00:00 2001 From: Adam Fedor Date: Mon, 23 May 2016 12:06:02 -0600 Subject: [PATCH 3/3] Test that predefined objects get deallocated --- Cocoa Script.xcodeproj/project.pbxproj | 4 ++ CocoaScriptTests/CSPropertyTests.m | 12 ++-- .../MochaRuntimeObjectStorateTests.m | 57 +++++++++++++++++++ 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 CocoaScriptTests/MochaRuntimeObjectStorateTests.m diff --git a/Cocoa Script.xcodeproj/project.pbxproj b/Cocoa Script.xcodeproj/project.pbxproj index d8c9f47..8177086 100644 --- a/Cocoa Script.xcodeproj/project.pbxproj +++ b/Cocoa Script.xcodeproj/project.pbxproj @@ -357,6 +357,7 @@ CCF4DBE118296AB800ACB9EC /* Mocha.m in Sources */ = {isa = PBXBuildFile; fileRef = CC66D861181A2AE10039A0A5 /* Mocha.m */; }; CCF4DBE218296AB800ACB9EC /* MochaRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = CC66D865181A2AE10039A0A5 /* MochaRuntime.m */; }; CCF68F1E0F4E3E4F00925FCA /* JSTalkDocument.icns in Resources */ = {isa = PBXBuildFile; fileRef = CCF68F1D0F4E3E4F00925FCA /* JSTalkDocument.icns */; }; + F34CC6641CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F34CC6631CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -674,6 +675,7 @@ CCF056171849A23C000C56F7 /* COSScript+Spelunking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "COSScript+Spelunking.m"; path = "src/framework/COSScript+Spelunking.m"; sourceTree = ""; }; CCF0561C184A884D000C56F7 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = ../../../../System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; CCF68F1D0F4E3E4F00925FCA /* JSTalkDocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = JSTalkDocument.icns; path = res/images/JSTalkDocument.icns; sourceTree = ""; }; + F34CC6631CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MochaRuntimeObjectStorateTests.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -835,6 +837,7 @@ children = ( 9FC343D61AF7D33300B53759 /* CSPropertyTests.m */, 9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */, + F34CC6631CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m */, 9F5068D31B4B20B400A2218F /* Resources */, 9FC343C91AF7D2FE00B53759 /* Supporting Files */, ); @@ -1517,6 +1520,7 @@ files = ( 9FC343D71AF7D33300B53759 /* CSPropertyTests.m in Sources */, 9F5068DD1B4B20BB00A2218F /* GarbageCollectionTests.m in Sources */, + F34CC6641CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m in Sources */, 9FC343D51AF7D32B00B53759 /* Model.xcdatamodeld in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/CocoaScriptTests/CSPropertyTests.m b/CocoaScriptTests/CSPropertyTests.m index 572b5c9..e087131 100644 --- a/CocoaScriptTests/CSPropertyTests.m +++ b/CocoaScriptTests/CSPropertyTests.m @@ -67,11 +67,11 @@ - (void)setUp { moContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; model = [[NSManagedObjectModel alloc] initWithContentsOfURL: testModelURL]; coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: model]; - - NSPersistentStore *store = [coordinator addPersistentStoreWithType: NSInMemoryStoreType - configuration: nil - URL: [NSURL fileURLWithPath: @"/tmp/testmodel"] - options: 0 + + [coordinator addPersistentStoreWithType: NSInMemoryStoreType + configuration: nil + URL: [NSURL fileURLWithPath: @"/tmp/testmodel"] + options: 0 error: &error]; [moContext setPersistentStoreCoordinator: coordinator]; } @@ -106,7 +106,7 @@ - (void)testSetSubclassedManagedObjectProperty_ShouldReturnSimpleObject { NSManagedObject *modelObject = [NSEntityDescription insertNewObjectForEntityForName: @"Product" inManagedObjectContext: moContext]; [runtime evalString: @"function setTestProperty(object) { object.name = \"testValue\" }"]; - id result = [runtime callFunctionWithName:@"setTestProperty" withArgumentsInArray: @[modelObject]]; + [runtime callFunctionWithName:@"setTestProperty" withArgumentsInArray: @[modelObject]]; XCTAssertTrue([[modelObject valueForKey: @"name"] isEqualToString: @"testValue"], @"Property not set"); } diff --git a/CocoaScriptTests/MochaRuntimeObjectStorateTests.m b/CocoaScriptTests/MochaRuntimeObjectStorateTests.m new file mode 100644 index 0000000..f5038d0 --- /dev/null +++ b/CocoaScriptTests/MochaRuntimeObjectStorateTests.m @@ -0,0 +1,57 @@ +// +// MochaRuntimeObjectStorateTests.m +// Cocoa Script +// +// Created by Adam Fedor on 5/23/16. +// +// + +#import +#import "COScript.h" + +static NSInteger deallocCalled = 0; + +@interface GCObject : NSObject +@end +@implementation GCObject +- (void)dealloc +{ + deallocCalled += 1; +} +@end + +@interface MochaRuntimeObjectStorateTests : XCTestCase + +@end + +@implementation MochaRuntimeObjectStorateTests +{ + COScript *jsContext; +} + +- (void)setUp { + [super setUp]; + jsContext = [[COScript alloc] init]; + deallocCalled = 0; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testStoreAndRemoveObject_ShouldDeallocateIt { + @autoreleasepool { + NSObject *object = [[GCObject alloc] init]; + [jsContext pushObject: object withName: @"testObject"]; + [jsContext executeString: @"function add() { var newObject = testObject; return newObject}"]; + [jsContext callFunctionNamed: @"add" withArguments: nil]; + [jsContext deleteObjectWithName: @"testObject"]; + object = nil; + } + + [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]]; + + XCTAssert(deallocCalled == 1, @"Object not deallocated"); +} + +@end