Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various garbage collection Unit Tests #29

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions Cocoa Script.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
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 */; };
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 */; };
Expand Down Expand Up @@ -351,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 */
Expand Down Expand Up @@ -402,6 +409,12 @@
384830E01832D48500B34168 /* COSTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = COSTarget.h; path = src/framework/COSTarget.h; sourceTree = "<group>"; };
384830E11832D48500B34168 /* COSTarget.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = COSTarget.m; path = src/framework/COSTarget.m; sourceTree = "<group>"; };
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 = "<group>"; };
9F5068D51B4B20B400A2218F /* GarbageCollect2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = GarbageCollect2.js; sourceTree = "<group>"; };
9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = JSMemoryAllocation.js; sourceTree = "<group>"; };
9F5068D71B4B20B400A2218F /* MemoryAllocation.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = MemoryAllocation.js; sourceTree = "<group>"; };
9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GarbageCollectionTests.m; sourceTree = "<group>"; };
9F5068DE1B4B36BA00A2218F /* loadPlist.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = loadPlist.js; sourceTree = "<group>"; };
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 = "<group>"; };
9FC343D41AF7D32B00B53759 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
Expand Down Expand Up @@ -662,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 = "<group>"; };
CCF0561C184A884D000C56F7 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = ../../../../System/Library/Frameworks/OpenGL.framework; sourceTree = "<group>"; };
CCF68F1D0F4E3E4F00925FCA /* JSTalkDocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = JSTalkDocument.icns; path = res/images/JSTalkDocument.icns; sourceTree = "<group>"; };
F34CC6631CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MochaRuntimeObjectStorateTests.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -806,10 +820,25 @@
name = Frameworks;
sourceTree = "<group>";
};
9F5068D31B4B20B400A2218F /* Resources */ = {
isa = PBXGroup;
children = (
9F5068DE1B4B36BA00A2218F /* loadPlist.js */,
9F5068D41B4B20B400A2218F /* CoreGraphics.js */,
9F5068D51B4B20B400A2218F /* GarbageCollect2.js */,
9F5068D61B4B20B400A2218F /* JSMemoryAllocation.js */,
9F5068D71B4B20B400A2218F /* MemoryAllocation.js */,
);
path = Resources;
sourceTree = "<group>";
};
9FC343C81AF7D2FE00B53759 /* CocoaScriptTests */ = {
isa = PBXGroup;
children = (
9FC343D61AF7D33300B53759 /* CSPropertyTests.m */,
9F5068DC1B4B20BB00A2218F /* GarbageCollectionTests.m */,
F34CC6631CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m */,
9F5068D31B4B20B400A2218F /* Resources */,
9FC343C91AF7D2FE00B53759 /* Supporting Files */,
);
path = CocoaScriptTests;
Expand Down Expand Up @@ -1452,6 +1481,11 @@
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 */,
9F5068DF1B4B36BA00A2218F /* loadPlist.js in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1485,6 +1519,8 @@
buildActionMask = 2147483647;
files = (
9FC343D71AF7D33300B53759 /* CSPropertyTests.m in Sources */,
9F5068DD1B4B20BB00A2218F /* GarbageCollectionTests.m in Sources */,
F34CC6641CF3703A002FF620 /* MochaRuntimeObjectStorateTests.m in Sources */,
9FC343D51AF7D32B00B53759 /* Model.xcdatamodeld in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -2002,6 +2038,7 @@
9FC343D21AF7D2FE00B53759 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "Cocoa Script Editor" */ = {
isa = XCConfigurationList;
Expand Down
12 changes: 6 additions & 6 deletions CocoaScriptTests/CSPropertyTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down Expand Up @@ -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");
}
Expand Down
217 changes: 217 additions & 0 deletions CocoaScriptTests/GarbageCollectionTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
//
// GarbageCollectionTests.m
// Cocoa Script
//
// Created by Adam Fedor on 7/6/15.
//
//

#import <Cocoa/Cocoa.h>
#import <XCTest/XCTest.h>
#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");
}

/* 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
57 changes: 57 additions & 0 deletions CocoaScriptTests/MochaRuntimeObjectStorateTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// MochaRuntimeObjectStorateTests.m
// Cocoa Script
//
// Created by Adam Fedor on 5/23/16.
//
//

#import <XCTest/XCTest.h>
#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
Loading