1 import ExpoModulesTestCore
2 
3 @testable import ExpoModulesCore
4 
5 class JavaScriptRuntimeSpec: ExpoSpec {
6   override func spec() {
7     let runtime = JavaScriptRuntime()
8 
9     it("has global object accessible") {
10       expect(runtime.global) !== nil
11     }
12 
13     describe("eval") {
14       it("returns undefined") {
15         let undefined = try! runtime.eval("undefined")
16         expect(undefined.isUndefined()) == true
17         expect(undefined.kind) == .undefined
18         expect(undefined.isNull()) == false
19         expect(undefined.getRaw()).to(beNil())
20       }
21 
22       it("returns null") {
23         let null = try! runtime.eval("null")
24         expect(null.isNull()) == true
25         expect(null.kind) == .null
26         expect(null.getRaw()).to(beNil())
27       }
28 
29       it("returns bool") {
30         let boolTrue = try! runtime.eval("true")
31         let boolFalse = try! runtime.eval("false")
32         expect(boolTrue.isBool()) == true
33         expect(boolFalse.isBool()) == true
34         expect(boolTrue.kind) == .bool
35         expect(boolFalse.kind) == .bool
36         expect(try! boolTrue.asBool()) == true
37         expect(try! boolFalse.asBool()) == false
38       }
39 
40       it("returns number") {
41         let number = try! runtime.eval("1.23")
42         expect(number.isNumber()) == true
43         expect(number.kind) == .number
44         expect(try! number.asInt()) == 1
45         expect(try! number.asDouble()) == 1.23
46       }
47 
48       it("returns string") {
49         let string = try! runtime.eval("'foobar'")
50         expect(string.isString()) == true
51         expect(string.kind) == .string
52         expect(try! string.asString()) == "foobar"
53       }
54 
55       it("returns array") {
56         let array = try! runtime.eval("(['foo', 'bar'])")
57         expect(array.isObject()) == true
58         expect(array.kind) == .object
59         expect(try! array.asArray().map { try $0?.asString() }) == ["foo", "bar"]
60       }
61 
62       it("returns dict") {
63         let dict1 = try! runtime.eval("({ 'foo': 123 })")
64         let dict2 = try! runtime.eval("({ 'foo': 'bar' })")
65         expect(dict1.isObject()) == true
66         expect(dict2.isObject()) == true
67         expect(dict1.kind) == .object
68         expect(dict2.kind) == .object
69         expect(try! dict1.asDict() as? [String: Int]) == ["foo": 123]
70         expect(try! dict2.asDict() as? [String: String]) == ["foo": "bar"]
71       }
72 
73       it("returns function") {
74         let function = try! runtime.eval("(function() {})")
75         expect(function.isObject()) == true
76         expect(function.isFunction()) == true
77         expect(function.kind) == .function
78       }
79 
80       it("returns symbol") {
81         let symbol = try! runtime.eval("Symbol('foo')")
82         expect(symbol.isSymbol()) == true
83         expect(symbol.kind) == .symbol
84       }
85 
86       it("throws evaluation exception") {
87         expect({ try runtime.eval("foo") }).to(throwError { error in
88           expect(error).to(beAKindOf(JavaScriptEvalException.self))
89           #if canImport(reacthermes)
90           expect((error as! JavaScriptEvalException).reason).to(contain("Property 'foo' doesn't exist"))
91           #else
92           expect((error as! JavaScriptEvalException).reason).to(contain("Can't find variable: foo"))
93           #endif
94         })
95       }
96     }
97   }
98 }
99