Skip to content

Commit

Permalink
Merge pull request #27 from ruby/pr-b04fc4ce8c73d0790e5c40b952b1d3c83…
Browse files Browse the repository at this point in the history
…a9001ea

Add JS::Object#typeof method to test object type
  • Loading branch information
kateinoigakukun authored Jul 1, 2022
2 parents 176a0b0 + ded8983 commit e9c306e
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ext/js/bindgen/rb-js-abi-host.wit
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ js-value-to-string: function(value: js-abi-value) -> string
export-js-value-to-host: function(value: js-abi-value)
import-js-value-from-host: function() -> js-abi-value

js-value-typeof: function(value: js-abi-value) -> string

reflect-apply: function(target: js-abi-value, this-argument: js-abi-value, arguments: list<js-abi-value>) -> js-abi-value
reflect-construct: function(target: js-abi-value, arguments: list<js-abi-value>) -> js-abi-value
reflect-delete-property: function(target: js-abi-value, property-key: string) -> bool
Expand Down
20 changes: 20 additions & 0 deletions ext/js/js-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,25 @@ static VALUE _rb_js_obj_call(int argc, VALUE *argv, VALUE obj) {
rb_js_abi_host_reflect_apply(abi_method->abi, p->abi, &abi_args));
}

/*
* call-seq:
* js_value.typeof -> String
*
* Returns the result string of JavaScript 'typeof' operator.
* See also JS.is_a? for 'instanceof' operator.
* p JS.global.typeof # => "object"
* p JS.eval("return 1").typeof # => "number"
* p JS.eval("return 'str'").typeof # => "string"
* p JS.eval("return undefined").typeof # => "undefined"
* p JS.eval("return null").typeof # => "object"
*/
static VALUE _rb_js_obj_typeof(VALUE obj) {
struct jsvalue *p = check_jsvalue(obj);
rb_js_abi_host_string_t ret0;
rb_js_abi_host_js_value_typeof(p->abi, &ret0);
return rb_str_new(ret0.ptr, ret0.len);
}

/*
* call-seq:
* inspect -> string
Expand Down Expand Up @@ -319,6 +338,7 @@ void Init_js() {
rb_define_method(rb_cJS_Object, "[]", _rb_js_obj_aref, 1);
rb_define_method(rb_cJS_Object, "[]=", _rb_js_obj_aset, 2);
rb_define_method(rb_cJS_Object, "call", _rb_js_obj_call, -1);
rb_define_method(rb_cJS_Object, "typeof", _rb_js_obj_typeof, 0);
rb_define_method(rb_cJS_Object, "__export_to_js", _rb_js_export_to_js, 0);
rb_define_singleton_method(rb_cJS_Object, "__import_from_js", _rb_js_import_from_js, 0);
rb_define_method(rb_cJS_Object, "inspect", _rb_js_obj_inspect, 0);
Expand Down
3 changes: 3 additions & 0 deletions packages/npm-packages/ruby-wasm-wasi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ export class RubyVM {
return false;
}
},
jsValueTypeof(value) {
return typeof value;
},
reflectApply: function (target, thisArgument, args) {
return Reflect.apply(target as any, thisArgument, args);
},
Expand Down
12 changes: 12 additions & 0 deletions packages/npm-packages/ruby-wasm-wasi/test/js_from_rb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ describe("Manipulation of JS from Ruby", () => {
expect(vm.eval(code).toString()).toBe(String(props.result));
});

test.each([
{ object: `JS.eval('return 1')`, result: "number" },
{ object: `JS.eval('return "x"')`, result: "string" },
{ object: `JS.eval('return null')`, result: "object" },
{ object: `JS.eval('return undefined')`, result: "undefined" },
{ object: `JS.global`, result: "object" },
])("JS::Object#typeof (%s)", async (props) => {
const vm = await initRubyVM();
const code = `require "js"; (${props.object}).typeof`;
expect(vm.eval(code).toString()).toBe(String(props.result));
});

test.each([
{ expr: "JS.global[:Object]", result: Object },
{ expr: "JS.global[:Object][:keys]", result: Object.keys },
Expand Down

0 comments on commit e9c306e

Please sign in to comment.