opal-browser 0.2.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/build.yml +78 -0
  3. data/.gitignore +3 -0
  4. data/CHANGELOG.md +11 -0
  5. data/Gemfile +17 -3
  6. data/LICENSE +2 -1
  7. data/README.md +131 -54
  8. data/Rakefile +29 -1
  9. data/config.ru +20 -3
  10. data/docs/polyfills.md +24 -0
  11. data/examples/2048/Gemfile +6 -0
  12. data/examples/2048/README.md +13 -0
  13. data/examples/2048/app/application.rb +169 -0
  14. data/examples/2048/config.ru +9 -0
  15. data/examples/canvas/Gemfile +6 -0
  16. data/examples/canvas/README.md +9 -0
  17. data/examples/canvas/app/application.rb +55 -0
  18. data/examples/canvas/config.ru +9 -0
  19. data/examples/component/Gemfile +6 -0
  20. data/examples/component/README.md +10 -0
  21. data/examples/component/app/application.rb +66 -0
  22. data/examples/component/config.ru +9 -0
  23. data/examples/integrations/README.md +24 -0
  24. data/examples/integrations/dynamic-rack-opal-sprockets-server/Gemfile +6 -0
  25. data/examples/integrations/dynamic-rack-opal-sprockets-server/README.md +16 -0
  26. data/examples/integrations/dynamic-rack-opal-sprockets-server/app/application.rb +6 -0
  27. data/examples/integrations/dynamic-rack-opal-sprockets-server/config.ru +9 -0
  28. data/examples/integrations/dynamic-roda-roda-sprockets/.gitignore +1 -0
  29. data/examples/integrations/dynamic-roda-roda-sprockets/Gemfile +7 -0
  30. data/examples/integrations/dynamic-roda-roda-sprockets/README.md +22 -0
  31. data/examples/integrations/dynamic-roda-roda-sprockets/Rakefile +4 -0
  32. data/examples/integrations/dynamic-roda-roda-sprockets/app/application.rb +6 -0
  33. data/examples/integrations/dynamic-roda-roda-sprockets/app.rb +32 -0
  34. data/examples/integrations/dynamic-roda-roda-sprockets/config.ru +3 -0
  35. data/examples/integrations/dynamic-roda-tilt/.gitignore +1 -0
  36. data/examples/integrations/dynamic-roda-tilt/Gemfile +8 -0
  37. data/examples/integrations/dynamic-roda-tilt/README.md +17 -0
  38. data/examples/integrations/dynamic-roda-tilt/Rakefile +6 -0
  39. data/examples/integrations/dynamic-roda-tilt/app/application.rb +6 -0
  40. data/examples/integrations/dynamic-roda-tilt/app.rb +50 -0
  41. data/examples/integrations/dynamic-roda-tilt/config.ru +3 -0
  42. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/Gemfile +7 -0
  43. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/README.md +16 -0
  44. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/app/application.rb +6 -0
  45. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/config.ru +29 -0
  46. data/examples/integrations/static-bash/.gitignore +2 -0
  47. data/examples/integrations/static-bash/Gemfile +3 -0
  48. data/examples/integrations/static-bash/README.md +8 -0
  49. data/examples/integrations/static-bash/app/application.rb +6 -0
  50. data/examples/integrations/static-bash/build.sh +4 -0
  51. data/examples/integrations/static-bash/index.html +10 -0
  52. data/examples/integrations/static-bash-opal-parser/.gitignore +3 -0
  53. data/examples/integrations/static-bash-opal-parser/Gemfile +3 -0
  54. data/examples/integrations/static-bash-opal-parser/README.md +10 -0
  55. data/examples/integrations/static-bash-opal-parser/build.sh +4 -0
  56. data/examples/integrations/static-bash-opal-parser/index.html +19 -0
  57. data/examples/integrations/static-rake/.gitignore +1 -0
  58. data/examples/integrations/static-rake/Gemfile +4 -0
  59. data/examples/integrations/static-rake/README.md +7 -0
  60. data/examples/integrations/static-rake/Rakefile +10 -0
  61. data/examples/integrations/static-rake/app/application.rb +6 -0
  62. data/examples/integrations/static-rake/index.html +9 -0
  63. data/examples/integrations/static-rake-guard/.gitignore +1 -0
  64. data/examples/integrations/static-rake-guard/Gemfile +6 -0
  65. data/examples/integrations/static-rake-guard/Guardfile +3 -0
  66. data/examples/integrations/static-rake-guard/README.md +10 -0
  67. data/examples/integrations/static-rake-guard/Rakefile +10 -0
  68. data/examples/integrations/static-rake-guard/app/application.rb +6 -0
  69. data/examples/integrations/static-rake-guard/index.html +9 -0
  70. data/examples/svg/.gitignore +1 -0
  71. data/examples/svg/Gemfile +4 -0
  72. data/examples/svg/README.md +7 -0
  73. data/examples/svg/Rakefile +10 -0
  74. data/examples/svg/app/application.rb +11 -0
  75. data/examples/svg/index.html +17 -0
  76. data/examples/svg/index.svg +6 -0
  77. data/index.html.erb +2 -3
  78. data/opal/browser/audio/node.rb +121 -0
  79. data/opal/browser/audio/param_schedule.rb +43 -0
  80. data/opal/browser/audio.rb +66 -0
  81. data/opal/browser/blob.rb +94 -0
  82. data/opal/browser/canvas/data.rb +1 -1
  83. data/opal/browser/canvas/gradient.rb +1 -1
  84. data/opal/browser/canvas/style.rb +3 -1
  85. data/opal/browser/canvas/text.rb +1 -1
  86. data/opal/browser/canvas.rb +17 -3
  87. data/opal/browser/console.rb +3 -1
  88. data/opal/browser/cookies.rb +72 -34
  89. data/opal/browser/crypto.rb +79 -0
  90. data/opal/browser/css/declaration.rb +1 -1
  91. data/opal/browser/css/rule.rb +1 -1
  92. data/opal/browser/css/style_sheet.rb +2 -2
  93. data/opal/browser/css.rb +23 -7
  94. data/opal/browser/database/sql.rb +7 -8
  95. data/opal/browser/delay.rb +16 -0
  96. data/opal/browser/dom/attribute.rb +1 -1
  97. data/opal/browser/dom/builder.rb +29 -10
  98. data/opal/browser/dom/document.rb +81 -13
  99. data/opal/browser/dom/document_fragment.rb +18 -0
  100. data/opal/browser/dom/document_or_shadow_root.rb +19 -0
  101. data/opal/browser/dom/element/attributes.rb +28 -4
  102. data/opal/browser/dom/element/button.rb +31 -0
  103. data/opal/browser/dom/element/custom.rb +177 -0
  104. data/opal/browser/dom/element/data.rb +17 -2
  105. data/opal/browser/dom/element/editable.rb +47 -0
  106. data/opal/browser/dom/element/form.rb +38 -0
  107. data/opal/browser/dom/element/iframe.rb +37 -0
  108. data/opal/browser/dom/element/image.rb +2 -0
  109. data/opal/browser/dom/element/input.rb +36 -0
  110. data/opal/browser/dom/element/media.rb +17 -0
  111. data/opal/browser/dom/element/scroll.rb +106 -74
  112. data/opal/browser/dom/element/select.rb +6 -0
  113. data/opal/browser/dom/element/size.rb +12 -0
  114. data/opal/browser/dom/element/template.rb +2 -0
  115. data/opal/browser/dom/element/textarea.rb +2 -0
  116. data/opal/browser/dom/element.rb +194 -50
  117. data/opal/browser/dom/mutation_observer.rb +2 -2
  118. data/opal/browser/dom/node.rb +53 -13
  119. data/opal/browser/dom/node_set.rb +13 -2
  120. data/opal/browser/dom/shadow_root.rb +12 -0
  121. data/opal/browser/dom/text.rb +2 -2
  122. data/opal/browser/dom.rb +38 -5
  123. data/opal/browser/effects.rb +170 -4
  124. data/opal/browser/event/all.rb +26 -0
  125. data/opal/browser/event/animation.rb +2 -0
  126. data/opal/browser/event/audio_processing.rb +2 -0
  127. data/opal/browser/event/base.rb +35 -4
  128. data/opal/browser/event/before_unload.rb +2 -0
  129. data/opal/browser/event/clipboard.rb +9 -0
  130. data/opal/browser/event/close.rb +2 -0
  131. data/opal/browser/event/composition.rb +2 -0
  132. data/opal/browser/event/custom.rb +1 -1
  133. data/opal/browser/event/data_transfer.rb +95 -0
  134. data/opal/browser/event/device_light.rb +2 -0
  135. data/opal/browser/event/device_motion.rb +2 -0
  136. data/opal/browser/event/device_orientation.rb +2 -0
  137. data/opal/browser/event/device_proximity.rb +2 -0
  138. data/opal/browser/event/drag.rb +9 -5
  139. data/opal/browser/event/focus.rb +2 -0
  140. data/opal/browser/event/gamepad.rb +3 -1
  141. data/opal/browser/event/hash_change.rb +2 -0
  142. data/opal/browser/event/keyboard.rb +14 -1
  143. data/opal/browser/event/message.rb +2 -0
  144. data/opal/browser/event/mouse.rb +10 -6
  145. data/opal/browser/event/page_transition.rb +2 -0
  146. data/opal/browser/event/pop_state.rb +2 -0
  147. data/opal/browser/event/progress.rb +2 -0
  148. data/opal/browser/event/sensor.rb +2 -0
  149. data/opal/browser/event/storage.rb +2 -0
  150. data/opal/browser/event/touch.rb +2 -0
  151. data/opal/browser/event/wheel.rb +2 -0
  152. data/opal/browser/event.rb +26 -116
  153. data/opal/browser/event_source.rb +1 -1
  154. data/opal/browser/form_data.rb +225 -0
  155. data/opal/browser/history.rb +4 -8
  156. data/opal/browser/http/request.rb +32 -10
  157. data/opal/browser/http/response.rb +5 -1
  158. data/opal/browser/http.rb +0 -2
  159. data/opal/browser/immediate.rb +0 -2
  160. data/opal/browser/location.rb +7 -1
  161. data/opal/browser/navigator.rb +105 -4
  162. data/opal/browser/polyfill/visual_viewport.rb +216 -0
  163. data/opal/browser/screen.rb +2 -2
  164. data/opal/browser/setup/base.rb +6 -0
  165. data/opal/browser/setup/full.rb +13 -0
  166. data/opal/browser/setup/large.rb +17 -0
  167. data/opal/browser/setup/mini.rb +8 -0
  168. data/opal/browser/setup/traditional.rb +10 -0
  169. data/opal/browser/socket.rb +3 -3
  170. data/opal/browser/storage.rb +2 -2
  171. data/opal/browser/support.rb +46 -22
  172. data/opal/browser/utils.rb +94 -14
  173. data/opal/browser/version.rb +1 -1
  174. data/opal/browser/visual_viewport.rb +39 -0
  175. data/opal/browser/window/size.rb +14 -0
  176. data/opal/browser/window/view.rb +15 -0
  177. data/opal/browser/window.rb +29 -16
  178. data/opal/browser.rb +1 -11
  179. data/opal-browser.gemspec +3 -3
  180. data/spec/database/sql_spec.rb +43 -35
  181. data/spec/delay_spec.rb +15 -12
  182. data/spec/dom/document_spec.rb +10 -8
  183. data/spec/dom/element/custom_spec.rb +106 -0
  184. data/spec/dom/element/subclass_spec.rb +144 -0
  185. data/spec/dom/element_spec.rb +42 -0
  186. data/spec/dom/mutation_observer_spec.rb +12 -8
  187. data/spec/dom/node_spec.rb +48 -0
  188. data/spec/dom_spec.rb +8 -0
  189. data/spec/event_source_spec.rb +15 -12
  190. data/spec/{dom/event_spec.rb → event_spec.rb} +44 -15
  191. data/spec/history_spec.rb +23 -19
  192. data/spec/http_spec.rb +19 -31
  193. data/spec/immediate_spec.rb +5 -4
  194. data/spec/interval_spec.rb +18 -9
  195. data/spec/native_cached_wrapper_spec.rb +46 -0
  196. data/spec/runner.rb +37 -62
  197. data/spec/socket_spec.rb +15 -12
  198. data/spec/spec_helper.rb +2 -1
  199. data/spec/spec_helper_promise.rb.erb +25 -0
  200. metadata +120 -16
  201. data/.travis.yml +0 -74
  202. data/opal/browser/window/scroll.rb +0 -59
@@ -178,4 +178,46 @@ describe Browser::DOM::Element do
178
178
  expect($document.at_xpath('//div', '//span', '//[@id="lol"]')).to be_a(DOM::Element)
179
179
  end
180
180
  end
181
+
182
+ describe '#shadow' do
183
+ html <<-HTML
184
+ <div id="shadowtest"></div>
185
+ HTML
186
+
187
+ it 'creates a shadow root' do
188
+ expect($document[:shadowtest].shadow?).to be(false)
189
+ expect($document[:shadowtest].shadow).to be_a(DOM::ShadowRoot)
190
+ expect($document[:shadowtest].shadow?).to be(true)
191
+ end
192
+
193
+ it 'accesses a shadow root' do
194
+ $document[:shadowtest].shadow # Create one
195
+ expect($document[:shadowtest].shadow?).to be(true)
196
+ expect($document[:shadowtest].shadow).to be_a(DOM::ShadowRoot)
197
+ end
198
+
199
+ it 'works like a typical opal-browser DOM tree' do
200
+ DOM {
201
+ div.shadow_item "Hello world!"
202
+ }.append_to($document[:shadowtest].shadow)
203
+
204
+ expect($document[:shadowtest].at_css(".shadow_item")).to be_nil
205
+ expect($document[:shadowtest].shadow.at_css(".shadow_item").text).to be("Hello world!")
206
+ end
207
+
208
+ it 'supports stylesheets' do
209
+ $document[:shadowtest].shadow << CSS {
210
+ rule("p") {
211
+ color "rgb(255, 0, 0)"
212
+ }
213
+ rule(":host") {
214
+ color "rgb(0, 0, 255)"
215
+ }
216
+ } << DOM { p }
217
+
218
+ expect($document[:shadowtest].shadow.at_css("p").style!.color).to be("rgb(255, 0, 0)")
219
+ expect($document[:shadowtest].style!.color).to be("rgb(0, 0, 255)")
220
+ expect($document[:shadowtest].shadow.stylesheets.count).to be(1)
221
+ end
222
+ end
181
223
  end
@@ -7,11 +7,11 @@ describe Browser::DOM::MutationObserver do
7
7
  </div>
8
8
  HTML
9
9
 
10
- async 'notifies additions' do
10
+ it 'notifies additions' do
11
+ promise = Browser::Promise.new
11
12
  obs = Browser::DOM::MutationObserver.new {|mutations|
12
- async {
13
- expect(mutations.first.added.first.name).to eq('DIV')
14
- }
13
+ expect(mutations.first.added.first.name).to eq('DIV')
14
+ promise.resolve
15
15
 
16
16
  obs.disconnect
17
17
  }
@@ -19,13 +19,15 @@ describe Browser::DOM::MutationObserver do
19
19
  obs.observe $document[:mutate]
20
20
 
21
21
  $document[:mutate].add_child $document.create_element('div')
22
+
23
+ promise.for_rspec
22
24
  end
23
25
 
24
- async 'notifies removals' do
26
+ it 'notifies removals' do
27
+ promise = Browser::Promise.new
25
28
  obs = Browser::DOM::MutationObserver.new {|mutations|
26
- async {
27
- expect(mutations.first.removed.first.name).to eq('SPAN')
28
- }
29
+ expect(mutations.first.removed.first.name).to eq('SPAN')
30
+ promise.resolve
29
31
 
30
32
  obs.disconnect
31
33
  }
@@ -33,5 +35,7 @@ describe Browser::DOM::MutationObserver do
33
35
  obs.observe $document[:mutate]
34
36
 
35
37
  $document[:mutate].first_element_child.remove
38
+
39
+ promise.for_rspec
36
40
  end
37
41
  end if Browser::DOM::MutationObserver.supported?
@@ -18,6 +18,54 @@ describe Browser::DOM::Node do
18
18
  end
19
19
  end
20
20
 
21
+ describe "#clone" do
22
+ html '<div class="waht"><ul><li>1</li></ul></div>'
23
+
24
+ it 'should clone a DOM node with an object' do
25
+ obj = $document['.waht']
26
+ new_obj = obj.clone
27
+
28
+ expect(obj).not_to eq(new_obj) # Equality is defined as equality of DOM nodes
29
+ expect(obj.at_css('li')).not_to eq(new_obj.at_css('li'))
30
+ end
31
+
32
+ it 'should dup a DOM node with an object' do
33
+ obj = $document['.waht']
34
+ new_obj = obj.dup
35
+
36
+ expect(obj).not_to eq(new_obj) # Equality is defined as equality of DOM nodes
37
+ expect(obj.at_css('li')).not_to eq(new_obj.at_css('li'))
38
+ end
39
+
40
+ it 'should produce an object which adheres to DOM semantics' do
41
+ obj = $document['.waht'].clone
42
+ xobj = obj.clone
43
+ 5.times do
44
+ obj << xobj.clone
45
+ end
46
+ expect(obj.css('li').count).to eq(6)
47
+ end
48
+
49
+ it 'should integrate well with NativeCachedWrapper' do
50
+ obj = $document['.waht'].clone
51
+ native = obj.to_n
52
+ expect(DOM(native).hash).to eq(obj.hash)
53
+ end
54
+ end
55
+
56
+ describe "#document=" do
57
+ html '<iframe id="diframe" src="about:blank"></iframe><div id="ddiv">hah</div>'
58
+
59
+ it 'should detach a DOM node and attach it to a new document' do
60
+ obj = $document['ddiv']
61
+ ifr = $document['diframe']
62
+
63
+ obj.document = ifr.content_document
64
+ expect($document['ddiv']).to eq(nil)
65
+ expect(obj.document).to eq(ifr.content_document)
66
+ end
67
+ end
68
+
21
69
  describe "#document?" do
22
70
  it "should be true for document" do
23
71
  expect($document.document?).to be_truthy
data/spec/dom_spec.rb CHANGED
@@ -11,5 +11,13 @@ describe 'Kernel' do
11
11
  expect($document['.spec'].element?).to be_truthy
12
12
  expect($document['.sock'].element?).to be_truthy
13
13
  end
14
+
15
+ it "appends classes correctly" do
16
+ elem = DOM {
17
+ div.class1.class2(class: "class-3 class-4", classes: %w[class-5 class-6])
18
+ }
19
+
20
+ expect(elem =~ ".class1.class2.class-3.class-4.class-5.class-6").to eq(true)
21
+ end
14
22
  end
15
23
  end
@@ -2,41 +2,44 @@ require 'spec_helper'
2
2
  require 'browser/event_source'
3
3
 
4
4
  describe Browser::EventSource do
5
- async 'creates it' do
5
+ it 'creates it' do
6
+ promise = Browser::Promise.new
6
7
  Browser::EventSource.new '/events' do |es|
7
8
  es.on :open do |e|
8
9
  es.close
9
10
 
10
- async {
11
- expect(e.target).to be_a(Browser::EventSource)
12
- }
11
+ expect(e.target).to be_a(Browser::EventSource)
12
+ promise.resolve
13
13
  end
14
14
  end
15
+ promise.for_rspec
15
16
  end
16
17
 
17
- async 'receives an unnamed event' do
18
+ it 'receives an unnamed event' do
19
+ promise = Browser::Promise.new
18
20
  Browser::EventSource.new '/events' do |es|
19
21
  es.on :message do |e|
20
22
  e.off
21
23
  es.close
22
24
 
23
- async {
24
- expect(e.data).to eq('lol')
25
- }
25
+ expect(e.data).to eq('lol')
26
+ promise.resolve
26
27
  end
27
28
  end
29
+ promise.for_rspec
28
30
  end
29
31
 
30
- async 'receives a named event' do
32
+ it 'receives a named event' do
33
+ promise = Browser::Promise.new
31
34
  Browser::EventSource.new '/events' do |es|
32
35
  es.on :custom do |e|
33
36
  e.off
34
37
  es.close
35
38
 
36
- async {
37
- expect(e.data).to eq('omg')
38
- }
39
+ expect(e.data).to eq('omg')
40
+ promise.resolve
39
41
  end
40
42
  end
43
+ promise.for_rspec
41
44
  end
42
45
  end if Browser::EventSource.supported?
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
+ require 'browser/event'
2
3
 
3
- describe Browser::DOM::Event do
4
+ describe Browser::Event do
4
5
  html <<-HTML
5
6
  <div id="event-spec">
6
7
  u wot m8
@@ -40,39 +41,46 @@ describe Browser::DOM::Event do
40
41
  expect(count).to eq(2)
41
42
  end
42
43
 
43
- async "passes an event to the handler" do
44
+ it "passes an event to the handler" do
44
45
  elem = $document["event-spec"]
45
46
 
47
+ promise = Browser::Promise.new
48
+
46
49
  elem.on :click do |event|
47
- async {
48
- expect(event).to be_a(Browser::DOM::Event)
49
- }
50
+ expect(event).to be_a(Browser::Event)
51
+ promise.resolve
50
52
  end
51
53
 
52
54
  elem.trigger :click
55
+
56
+ promise.for_rspec
53
57
  end
54
58
 
55
- async "passes additional arguments to the handler" do
59
+ it "passes additional arguments to the handler" do
56
60
  elem = $document["event-spec"]
57
61
 
62
+ promise = Browser::Promise.new
63
+
58
64
  elem.on :bazinga do |event, foo, bar, baz|
59
- async {
60
- expect(foo).to eq(1)
61
- expect(bar).to eq(2)
62
- expect(baz).to eq(3)
63
- }
65
+ expect(foo).to eq(1)
66
+ expect(bar).to eq(2)
67
+ expect(baz).to eq(3)
68
+ promise.resolve
64
69
  end
65
70
 
66
71
  elem.trigger :bazinga, 1, 2, 3
72
+
73
+ promise.for_rspec
67
74
  end
68
75
 
69
- async "works with delegated events" do
76
+ it "works with delegated events" do
70
77
  elem = $document["event-spec"]
71
78
 
79
+ promise = Browser::Promise.new
80
+
72
81
  elem.on :bazinga, 'span.nami' do
73
- async {
74
- expect(true).to be_truthy
75
- }
82
+ expect(true).to be_truthy
83
+ promise.resolve
76
84
  end
77
85
 
78
86
  elem.add_child DOM { span.nami }
@@ -80,6 +88,27 @@ describe Browser::DOM::Event do
80
88
  after 0.01 do
81
89
  elem.first_element_child.trigger :bazinga
82
90
  end
91
+
92
+ promise.for_rspec
93
+ end
94
+ end
95
+
96
+ describe "#one" do
97
+ it "fires once, passes arguments, works with custom events" do
98
+ count = 0
99
+ elem = $document["event-spec"]
100
+
101
+ elem.one :testone do |event, a, b, c|
102
+ count += a + b*c
103
+ end
104
+
105
+ expect(count).to eq(0)
106
+ elem.trigger :testone, 1, 2, 3
107
+ expect(count).to eq(7)
108
+ elem.trigger :testone, 2, 3, 4
109
+ expect(count).to eq(7)
110
+ elem.trigger :testone, 3, 4, 5
111
+ expect(count).to eq(7)
83
112
  end
84
113
  end
85
114
 
data/spec/history_spec.rb CHANGED
@@ -19,39 +19,43 @@ describe Browser::History do
19
19
  end
20
20
 
21
21
  describe '#back' do
22
- async 'should go back once' do
22
+ it 'should go back once' do
23
23
  expect($window.history.current).to eq('/')
24
24
  $window.history.push('/wut')
25
25
  expect($window.history.current).to eq('/wut')
26
26
 
27
- $window.on 'pop:state' do |e|
28
- e.off
27
+ promise = Browser::Promise.new
29
28
 
30
- async {
31
- expect($window.history.current).to eq('/')
32
- }
29
+ $window.one 'pop:state' do |e|
30
+ expect($window.history.current).to eq('/')
31
+ promise.resolve
33
32
  end
34
33
 
35
34
  $window.history.back
35
+ promise.for_rspec
36
36
  end
37
37
  end
38
38
 
39
39
  describe '#state' do
40
- async 'gets the right state' do
41
- $window.history.push('/wut', 42)
42
- $window.history.state.should eq(42)
43
- $window.history.push('/omg', 23)
44
- $window.history.state.should eq(23)
45
-
46
- $window.on 'pop:state' do |e|
47
- e.off
48
-
49
- async {
40
+ it 'gets the right state' do
41
+ # XX: The previous test creates a race condition with this one.
42
+ # Adding a delay fixes it.
43
+ promise = Browser::Promise.new
44
+
45
+ after 0.05 do
46
+ $window.history.push('/wut', 42)
47
+ $window.history.state.should eq(42)
48
+ $window.history.push('/omg', 23)
49
+ $window.history.state.should eq(23)
50
+
51
+ $window.one 'pop:state' do |e|
50
52
  expect(true).to eq(true)
51
- }
52
- end
53
+ promise.resolve
54
+ end
53
55
 
54
- $window.history.back(2)
56
+ $window.history.back(2)
57
+ end
58
+ promise.for_rspec
55
59
  end
56
60
  end if Browser.supports? 'History.state'
57
61
  end if Browser::History.supported?
data/spec/http_spec.rb CHANGED
@@ -2,20 +2,15 @@ require 'spec_helper'
2
2
  require 'browser/http'
3
3
 
4
4
  describe Browser::HTTP do
5
- let :path do
6
- '/http'
7
- end
5
+ let(:path) { '/http' }
6
+ let(:path_file) { '/http-file' }
8
7
 
9
8
  describe '.get' do
10
- async 'fetches a path' do
9
+ it 'fetches a path' do
11
10
  Browser::HTTP.get(path).then {|res|
12
- async {
13
- expect(res.text).to eq('lol')
14
- }
11
+ expect(res.text).to eq('lol')
15
12
  }.rescue {
16
- async {
17
- fail
18
- }
13
+ fail
19
14
  }
20
15
  end
21
16
  end
@@ -27,15 +22,11 @@ describe Browser::HTTP do
27
22
  end
28
23
 
29
24
  describe '.post' do
30
- async 'sends parameters properly' do
25
+ it 'sends parameters properly' do
31
26
  Browser::HTTP.post(path, lol: 'wut').then {|res|
32
- async {
33
- expect(res.text).to eq('ok')
34
- }
27
+ expect(res.text).to eq('ok')
35
28
  }.rescue {
36
- async {
37
- fail
38
- }
29
+ fail
39
30
  }
40
31
  end
41
32
  end
@@ -44,18 +35,19 @@ describe Browser::HTTP do
44
35
  it 'sends parameters properly' do
45
36
  expect(Browser::HTTP.post!(path, lol: 'wut').text).to eq('ok')
46
37
  end
38
+
39
+ it 'sends files properly' do
40
+ file = Browser::File.create(["content"], "yay.txt", type: "text/plain")
41
+ expect(Browser::HTTP.post!(path_file, lol: 'wut', file: file).text).to eq('ok')
42
+ end
47
43
  end
48
44
 
49
45
  describe '.put' do
50
- async 'sends parameters properly' do
46
+ it 'sends parameters properly' do
51
47
  Browser::HTTP.put(path, lol: 'wut').then {|res|
52
- async {
53
- expect(res.text).to eq('ok')
54
- }
48
+ expect(res.text).to eq('ok')
55
49
  }.rescue {
56
- async {
57
- fail
58
- }
50
+ fail
59
51
  }
60
52
  end
61
53
  end
@@ -67,15 +59,11 @@ describe Browser::HTTP do
67
59
  end
68
60
 
69
61
  describe '.delete' do
70
- async 'fetches a path' do
62
+ it 'fetches a path' do
71
63
  Browser::HTTP.delete(path).then {|res|
72
- async {
73
- expect(res.text).to eq('lol')
74
- }
64
+ expect(res.text).to eq('lol')
75
65
  }.rescue {
76
- async {
77
- fail
78
- }
66
+ fail
79
67
  }
80
68
  end
81
69
  end
@@ -3,12 +3,13 @@ require 'browser/immediate'
3
3
 
4
4
  describe Proc do
5
5
  describe '#defer' do
6
- async 'defers the parameters' do
6
+ it 'defers the parameters' do
7
+ promise = Browser::Promise.new
7
8
  proc {|a|
8
- async {
9
- expect(a).to eq(42)
10
- }
9
+ expect(a).to eq(42)
10
+ promise.resolve
11
11
  }.defer(42)
12
+ promise.for_rspec
12
13
  end
13
14
  end
14
15
  end
@@ -3,48 +3,57 @@ require 'browser/interval'
3
3
 
4
4
  describe Browser::Window do
5
5
  describe '#every' do
6
- async 'calls the block multiple times' do
6
+ it 'calls the block multiple times' do
7
7
  x = 0
8
8
 
9
+ promise = Browser::Promise.new
9
10
  $window.every 0.3 do
10
11
  x += 1
11
12
 
12
- async {
13
+ if x == 3
13
14
  expect(true).to be_truthy
14
- } if x == 3
15
+ promise.resolve
16
+ end
15
17
  end
18
+ promise.for_rspec
16
19
  end
17
20
  end
18
21
  end
19
22
 
20
23
  describe Kernel do
21
24
  describe '#every' do
22
- async 'calls the block multiple times' do
25
+ it 'calls the block multiple times' do
23
26
  x = 0
24
27
 
28
+ promise = Browser::Promise.new
25
29
  every 0.3 do
26
30
  x += 1
27
31
 
28
- async {
32
+ if x == 3
29
33
  expect(true).to be_truthy
30
- } if x == 3
34
+ promise.resolve
35
+ end
31
36
  end
37
+ promise.for_rspec
32
38
  end
33
39
  end
34
40
  end
35
41
 
36
42
  describe Proc do
37
43
  describe '#every' do
38
- async 'calls the block multiple times' do
44
+ it 'calls the block multiple times' do
39
45
  x = 0
40
46
 
47
+ promise = Browser::Promise.new
41
48
  -> {
42
49
  x += 1
43
50
 
44
- async {
51
+ if x == 3
45
52
  expect(true).to be_truthy
46
- } if x == 3
53
+ promise.resolve
54
+ end
47
55
  }.every 0.3
56
+ promise.for_rspec
48
57
  end
49
58
  end
50
59
  end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Browser::NativeCachedWrapper do
4
+ it 'deduplicates DOM objects' do
5
+ expect($document.at_css("body").hash).to eq($document.body.hash)
6
+ expect($document.body.hash).not_to eq($document.body.dup.hash) # Should dup/clone have different semantics?
7
+ expect($document.body.hash).not_to eq($document.head.hash)
8
+ end
9
+
10
+ it 'accurately intercepts the last new call' do
11
+ class Demo
12
+ include Browser::NativeCachedWrapper
13
+
14
+ def self.new(arg1, arg2)
15
+ super(`{arg1: #{arg1}, arg2: #{arg2}}`)
16
+ end
17
+
18
+ def data
19
+ [:data, `#@native.arg1`, `#@native.arg2`]
20
+ end
21
+ end
22
+
23
+ class SuperDemo < Demo
24
+ def self.new(arg1, arg2, arg3)
25
+ super("superdemo", "#{arg1} - #{arg2} - #{arg3}")
26
+ end
27
+ end
28
+
29
+ expect(Demo.new("a", "b").data).to eq([:data, "a", "b"])
30
+ expect(SuperDemo.new("1", "2", "3").data).to eq([:data, "superdemo", "1 - 2 - 3"])
31
+ end
32
+
33
+ html <<-HTML
34
+ <iframe id='ifr' src='about:blank' sandbox=''></iframe>
35
+ HTML
36
+
37
+ it 'supports restricted objects' do
38
+ # Window won't be restricted
39
+ expect($window.restricted?).to eq(false)
40
+ # Iframe itself won't be restricted
41
+ expect($document['ifr'].restricted?).to eq(false)
42
+ # But its content_window will be (due to CORS)
43
+ expect($document['ifr'].content_window.restricted?).to eq(true)
44
+ end
45
+ end
46
+