]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - API/tests/JSExportTests.mm
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / API / tests / JSExportTests.mm
diff --git a/API/tests/JSExportTests.mm b/API/tests/JSExportTests.mm
new file mode 100644 (file)
index 0000000..9d22e3f
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "JSExportTests.h"
+
+#import <objc/runtime.h>
+#import <objc/objc.h>
+
+#if JSC_OBJC_API_ENABLED
+
+extern "C" void checkResult(NSString *description, bool passed);
+
+@interface JSExportTests : NSObject
++ (void) exportInstanceMethodWithIdProtocolTest;
++ (void) exportInstanceMethodWithClassProtocolTest;
++ (void) exportDynamicallyGeneratedProtocolTest;
+@end
+
+@protocol TruthTeller
+- (BOOL) returnTrue;
+@end
+
+@interface TruthTeller : NSObject<TruthTeller>
+@end
+
+@implementation TruthTeller
+- (BOOL) returnTrue
+{
+    return true;
+}
+@end
+
+@protocol ExportMethodWithIdProtocol <JSExport>
+- (void) methodWithIdProtocol:(id<TruthTeller>)object;
+@end
+
+@interface ExportMethodWithIdProtocol : NSObject<ExportMethodWithIdProtocol>
+@end
+
+@implementation ExportMethodWithIdProtocol
+- (void) methodWithIdProtocol:(id<TruthTeller>)object
+{
+    checkResult(@"Exporting a method with id<protocol> in the type signature", [object returnTrue]);
+}
+@end
+
+@protocol ExportMethodWithClassProtocol <JSExport>
+- (void) methodWithClassProtocol:(NSObject<TruthTeller> *)object;
+@end
+
+@interface ExportMethodWithClassProtocol : NSObject<ExportMethodWithClassProtocol>
+@end
+
+@implementation ExportMethodWithClassProtocol
+- (void) methodWithClassProtocol:(NSObject<TruthTeller> *)object
+{
+    checkResult(@"Exporting a method with class<protocol> in the type signature", [object returnTrue]);
+}
+@end
+
+@implementation JSExportTests
++ (void) exportInstanceMethodWithIdProtocolTest
+{
+    JSContext *context = [[JSContext alloc] init];
+    context[@"ExportMethodWithIdProtocol"] = [ExportMethodWithIdProtocol class];
+    context[@"makeTestObject"] = ^{
+        return [[ExportMethodWithIdProtocol alloc] init];
+    };
+    context[@"opaqueObject"] = [[TruthTeller alloc] init];
+    [context evaluateScript:@"makeTestObject().methodWithIdProtocol(opaqueObject);"];
+    checkResult(@"Successfully exported instance method", !context.exception);
+}
+
++ (void) exportInstanceMethodWithClassProtocolTest
+{
+    JSContext *context = [[JSContext alloc] init];
+    context[@"ExportMethodWithClassProtocol"] = [ExportMethodWithClassProtocol class];
+    context[@"makeTestObject"] = ^{
+        return [[ExportMethodWithClassProtocol alloc] init];
+    };
+    context[@"opaqueObject"] = [[TruthTeller alloc] init];
+    [context evaluateScript:@"makeTestObject().methodWithClassProtocol(opaqueObject);"];
+    checkResult(@"Successfully exported instance method", !context.exception);
+}
+
++ (void) exportDynamicallyGeneratedProtocolTest
+{
+    JSContext *context = [[JSContext alloc] init];
+    Protocol *dynProtocol = objc_allocateProtocol("NSStringJSExport");
+    Protocol *jsExportProtocol = @protocol(JSExport);
+    protocol_addProtocol(dynProtocol, jsExportProtocol);
+    Method method = class_getInstanceMethod([NSString class], @selector(boolValue));
+    protocol_addMethodDescription(dynProtocol, @selector(boolValue), method_getTypeEncoding(method), YES, YES);
+    NSLog(@"type encoding = %s", method_getTypeEncoding(method));
+    protocol_addMethodDescription(dynProtocol, @selector(boolValue), "B@:", YES, YES);
+    objc_registerProtocol(dynProtocol);
+    class_addProtocol([NSString class], dynProtocol);
+    
+    context[@"NSString"] = [NSString class];
+    context[@"myString"] = @"YES";
+    JSValue *value = [context evaluateScript:@"myString.boolValue()"];
+    checkResult(@"Dynamically generated JSExport-ed protocols are ignored", [value isUndefined] && !!context.exception);
+}
+@end
+
+void runJSExportTests()
+{
+    @autoreleasepool {
+        [JSExportTests exportInstanceMethodWithIdProtocolTest];
+        [JSExportTests exportInstanceMethodWithClassProtocolTest];
+        [JSExportTests exportDynamicallyGeneratedProtocolTest];
+    }
+}
+
+#endif // JSC_OBJC_API_ENABLED