-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathhook_spec.rb
161 lines (134 loc) · 5.3 KB
/
hook_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
gem 'minitest'
require 'minitest/autorun'
require 'ruby2js/filter/react'
require 'ruby2js/filter/functions'
require 'ruby2js/filter/jsx'
require 'ruby2js/filter/esm'
describe 'Ruby2JS::Filter::Hooks' do
def to_js(string)
_(Ruby2JS.convert(string, eslevel: 2015, scope: self,
filters: [Ruby2JS::Filter::React, Ruby2JS::Filter::Functions]).to_s)
end
def to_esm(string)
_(Ruby2JS.convert(string, eslevel: 2015,
filters: [Ruby2JS::Filter::React, Ruby2JS::Filter::ESM]).to_s)
end
describe :createClass do
it "should create classes" do
to_js( 'class Foo<React; end' ).
must_equal 'function Foo() {}'
end
it "should convert initialize methods to getInitialState" do
to_js( 'class Foo<React; def initialize(); end; end' ).
must_include 'function Foo() {}'
end
it "should call useState for instance variables" do
to_js( 'class Foo<React; def foo(); @i=1; end; end' ).
must_include 'let [i, setI] = React.useState(null)'
to_js( 'class Foo<React; def initialize(); @i=1; end; end' ).
must_include 'let [i, setI] = React.useState(1)'
to_js( 'class Foo<React; def initialize(); @i=1 if @@i; end; end' ).
must_include 'let [i, setI] = React.useState(null)'
end
it "should not autobind event handlers" do
to_js( 'class Foo<React; def render; _a onClick: handleClick; end; ' +
'def handleClick(event); end; end' ).
must_include '{onClick: handleClick}'
end
it "should handle parallel instance variable assignments" do
to_js( 'class Foo<React; def initialize; @a=@b=1; end; end' ).
must_include 'let [a, setA] = React.useState(1); ' +
'let [b, setB] = React.useState(1)'
end
it "should handle operator assignments on state values" do
to_js( 'class Foo<React; def foo(); @a+=1; end; end' ).
must_include '{setA(a + 1)}'
end
it "should handle calls to methods" do
to_js( 'class Foo<React; def a(); b(); end; def b(); end; end' ).
must_include '{b()}'
end
it "should NOT handle local variables" do
to_js( 'class Foo<React; def a(); b; end; end' ).
wont_include 'this.b()'
end
end
describe "map gvars/ivars/cvars to refs/state/prop" do
it "should map instance variables to state" do
to_js( 'class Foo<React; def method(); @x; end; end' ).
must_include '{x}'
end
it "should map setting instance variables to setState" do
to_js( 'class Foo<React; def method(); @x=1; end; end' ).
must_include '{setX(1)}'
end
it "should map parallel instance variables to setState" do
to_js( 'class Foo<React; def method(); @x=@y=1; end; end' ).
must_include 'setX(setY(1))'
end
it "should not create temporary variables for ivars" do
to_js( 'class Foo<React; def f(); @a+=1; b=@a; end; end' ).
must_include 'setA(a + 1); let b = a'
end
it "should treat singleton method definitions as a separate scope" do
js = to_js( 'class F < React; def m(); def x.a; @i=1; end; return @i; end; end' )
js.must_include 'setI(1)'
js.must_include 'return i'
end
it "should generate code to handle instance vars within singleton method" do
js = to_js('class F < React; def m(); def x.a; @i=1; @i+1; end; end; end')
js.must_include 'setI(1)'
js.must_include 'return i + 1'
end
it "should map class variables to properties" do
to_js( 'class Foo<React; def method(); @@x; end; end' ).
must_include 'prop$.x'
end
end
describe "method calls" do
it "should handle ivars" do
to_js( 'class Foo<React; def method(); @x.(); end; end' ).
must_include 'x()'
end
it "should handle cvars" do
to_js( 'class Foo<React; def method(); @@x.(); end; end' ).
must_include 'prop$.x()'
end
end
describe "controlled components" do
it "should should automatically create onInput value functions" do
to_js( 'class Foo<React; def render; _input value: @x; end; end' ).
must_include 'onChange(event) {setX(event.target.value)}'
end
it "should should automatically create onInput checked functions" do
to_js( 'class Foo<React; def render; _input checked: @x; end; end' ).
must_include 'onChange() {setX(!x)}'
end
it "should should retain onInput functions" do
to_js( 'class Foo<React; def render; _input checked: @x, onInput: change; end; end' ).
must_include 'onInput: change'
end
end
describe "props" do
it "should add props arg to function if needed" do
to_js( 'class Foo<React; def initialize; @x=@@y; end; end' ).
must_equal 'function Foo(prop$) {let [x, setX] = React.useState(prop$.y)}'
end
end
describe :autoimports do
it "should autoimport React" do
to_esm( 'class Foo<React; end' ).
must_include 'import React from "react";'
end
it "should autoimport Preact" do
to_esm( 'class Foo<Preact; end' ).
must_include 'import * as Preact from "preact";'
end
it "should autoimport Preact useState" do
to_esm( 'class Foo<Preact; def initialize; @i=1; end; end' ).
must_include 'import { useState } from "preact/hooks"'
to_esm( 'class Foo<Preact; def initialize; @i=1; end; end' ).
must_include 'let [i, setI] = useState(1)'
end
end
end