shoes-core 4.0.0.pre3

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 (219) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +31 -0
  3. data/README.md +8 -0
  4. data/Rakefile +1 -0
  5. data/bin/shoes +62 -0
  6. data/bin/shoes-guard +8 -0
  7. data/bin/shoes-picker +6 -0
  8. data/bin/shoes-stub +62 -0
  9. data/ext/install/Rakefile +29 -0
  10. data/ext/install/shoes.bat +15 -0
  11. data/fonts/Coolvetica.ttf +0 -0
  12. data/fonts/Lacuna.ttf +0 -0
  13. data/lib/rubygems_plugin.rb +24 -0
  14. data/lib/shoes.rb +1 -0
  15. data/lib/shoes/animation.rb +56 -0
  16. data/lib/shoes/app.rb +130 -0
  17. data/lib/shoes/arc.rb +25 -0
  18. data/lib/shoes/background.rb +20 -0
  19. data/lib/shoes/border.rb +20 -0
  20. data/lib/shoes/builtin_methods.rb +76 -0
  21. data/lib/shoes/button.rb +29 -0
  22. data/lib/shoes/check_button.rb +41 -0
  23. data/lib/shoes/color.rb +387 -0
  24. data/lib/shoes/common/background_element.rb +9 -0
  25. data/lib/shoes/common/changeable.rb +34 -0
  26. data/lib/shoes/common/clickable.rb +24 -0
  27. data/lib/shoes/common/inspect.rb +14 -0
  28. data/lib/shoes/common/positioning.rb +30 -0
  29. data/lib/shoes/common/registration.rb +31 -0
  30. data/lib/shoes/common/remove.rb +10 -0
  31. data/lib/shoes/common/state.rb +16 -0
  32. data/lib/shoes/common/style.rb +160 -0
  33. data/lib/shoes/common/style_normalizer.rb +16 -0
  34. data/lib/shoes/common/ui_element.rb +11 -0
  35. data/lib/shoes/common/visibility.rb +41 -0
  36. data/lib/shoes/configuration.rb +96 -0
  37. data/lib/shoes/core.rb +1 -0
  38. data/lib/shoes/core/version.rb +5 -0
  39. data/lib/shoes/dialog.rb +56 -0
  40. data/lib/shoes/dimension.rb +269 -0
  41. data/lib/shoes/dimensions.rb +203 -0
  42. data/lib/shoes/download.rb +130 -0
  43. data/lib/shoes/dsl.rb +656 -0
  44. data/lib/shoes/file_not_found_error.rb +4 -0
  45. data/lib/shoes/font.rb +50 -0
  46. data/lib/shoes/gradient.rb +31 -0
  47. data/lib/shoes/image.rb +53 -0
  48. data/lib/shoes/image_pattern.rb +12 -0
  49. data/lib/shoes/input_box.rb +59 -0
  50. data/lib/shoes/internal_app.rb +230 -0
  51. data/lib/shoes/key_event.rb +17 -0
  52. data/lib/shoes/line.rb +84 -0
  53. data/lib/shoes/link.rb +57 -0
  54. data/lib/shoes/link_hover.rb +5 -0
  55. data/lib/shoes/list_box.rb +50 -0
  56. data/lib/shoes/logger.rb +65 -0
  57. data/lib/shoes/logger/ruby.rb +16 -0
  58. data/lib/shoes/mock.rb +33 -0
  59. data/lib/shoes/mock/animation.rb +8 -0
  60. data/lib/shoes/mock/app.rb +49 -0
  61. data/lib/shoes/mock/arc.rb +9 -0
  62. data/lib/shoes/mock/background.rb +10 -0
  63. data/lib/shoes/mock/border.rb +7 -0
  64. data/lib/shoes/mock/button.rb +22 -0
  65. data/lib/shoes/mock/check.rb +24 -0
  66. data/lib/shoes/mock/clickable.rb +8 -0
  67. data/lib/shoes/mock/common_methods.rb +12 -0
  68. data/lib/shoes/mock/dialog.rb +13 -0
  69. data/lib/shoes/mock/download.rb +16 -0
  70. data/lib/shoes/mock/font.rb +15 -0
  71. data/lib/shoes/mock/image.rb +13 -0
  72. data/lib/shoes/mock/image_pattern.rb +8 -0
  73. data/lib/shoes/mock/input_box.rb +30 -0
  74. data/lib/shoes/mock/keypress.rb +11 -0
  75. data/lib/shoes/mock/keyrelease.rb +11 -0
  76. data/lib/shoes/mock/line.rb +14 -0
  77. data/lib/shoes/mock/link.rb +11 -0
  78. data/lib/shoes/mock/list_box.rb +19 -0
  79. data/lib/shoes/mock/oval.rb +11 -0
  80. data/lib/shoes/mock/packager.rb +13 -0
  81. data/lib/shoes/mock/progress.rb +10 -0
  82. data/lib/shoes/mock/radio.rb +27 -0
  83. data/lib/shoes/mock/rect.rb +14 -0
  84. data/lib/shoes/mock/shape.rb +20 -0
  85. data/lib/shoes/mock/slot.rb +16 -0
  86. data/lib/shoes/mock/sound.rb +8 -0
  87. data/lib/shoes/mock/star.rb +14 -0
  88. data/lib/shoes/mock/text_block.rb +36 -0
  89. data/lib/shoes/mock/timer.rb +8 -0
  90. data/lib/shoes/not_implemented_error.rb +4 -0
  91. data/lib/shoes/oval.rb +20 -0
  92. data/lib/shoes/packager.rb +26 -0
  93. data/lib/shoes/point.rb +54 -0
  94. data/lib/shoes/progress.rb +25 -0
  95. data/lib/shoes/radio.rb +15 -0
  96. data/lib/shoes/rect.rb +21 -0
  97. data/lib/shoes/renamed_delegate.rb +15 -0
  98. data/lib/shoes/shape.rb +159 -0
  99. data/lib/shoes/slot.rb +276 -0
  100. data/lib/shoes/slot_contents.rb +51 -0
  101. data/lib/shoes/sound.rb +18 -0
  102. data/lib/shoes/span.rb +16 -0
  103. data/lib/shoes/star.rb +50 -0
  104. data/lib/shoes/text.rb +24 -0
  105. data/lib/shoes/text_block.rb +142 -0
  106. data/lib/shoes/text_block_dimensions.rb +51 -0
  107. data/lib/shoes/timer.rb +14 -0
  108. data/lib/shoes/ui/cli.rb +67 -0
  109. data/lib/shoes/ui/picker.rb +47 -0
  110. data/lib/shoes/url.rb +44 -0
  111. data/lib/shoes/version.rb +3 -0
  112. data/lib/shoes/widget.rb +67 -0
  113. data/shoes-core.gemspec +22 -0
  114. data/spec/shoes/animation_spec.rb +71 -0
  115. data/spec/shoes/app_spec.rb +484 -0
  116. data/spec/shoes/arc_spec.rb +51 -0
  117. data/spec/shoes/background_spec.rb +47 -0
  118. data/spec/shoes/border_spec.rb +46 -0
  119. data/spec/shoes/builtin_methods_spec.rb +110 -0
  120. data/spec/shoes/button_spec.rb +44 -0
  121. data/spec/shoes/check_spec.rb +35 -0
  122. data/spec/shoes/color_spec.rb +408 -0
  123. data/spec/shoes/common/inspect_spec.rb +26 -0
  124. data/spec/shoes/common/remove_spec.rb +38 -0
  125. data/spec/shoes/common/style_normalizer_spec.rb +28 -0
  126. data/spec/shoes/common/style_spec.rb +147 -0
  127. data/spec/shoes/configuration_spec.rb +36 -0
  128. data/spec/shoes/constants_spec.rb +38 -0
  129. data/spec/shoes/dialog_spec.rb +171 -0
  130. data/spec/shoes/dimension_spec.rb +433 -0
  131. data/spec/shoes/dimensions_spec.rb +837 -0
  132. data/spec/shoes/download_spec.rb +146 -0
  133. data/spec/shoes/flow_spec.rb +133 -0
  134. data/spec/shoes/font_spec.rb +37 -0
  135. data/spec/shoes/framework_learning_spec.rb +30 -0
  136. data/spec/shoes/gradient_spec.rb +32 -0
  137. data/spec/shoes/helpers/fake_element.rb +17 -0
  138. data/spec/shoes/helpers/inspect_helpers.rb +5 -0
  139. data/spec/shoes/helpers/sample17_helper.rb +66 -0
  140. data/spec/shoes/image_spec.rb +68 -0
  141. data/spec/shoes/images/shoe.jpg +0 -0
  142. data/spec/shoes/input_box_spec.rb +80 -0
  143. data/spec/shoes/integration_spec.rb +20 -0
  144. data/spec/shoes/internal_app_spec.rb +141 -0
  145. data/spec/shoes/keypress_spec.rb +11 -0
  146. data/spec/shoes/keyrelease_spec.rb +12 -0
  147. data/spec/shoes/line_spec.rb +87 -0
  148. data/spec/shoes/link_spec.rb +118 -0
  149. data/spec/shoes/list_box_spec.rb +74 -0
  150. data/spec/shoes/logger/ruby_spec.rb +8 -0
  151. data/spec/shoes/logger_spec.rb +45 -0
  152. data/spec/shoes/oval_spec.rb +24 -0
  153. data/spec/shoes/packager_spec.rb +25 -0
  154. data/spec/shoes/point_spec.rb +71 -0
  155. data/spec/shoes/progress_spec.rb +54 -0
  156. data/spec/shoes/radio_spec.rb +32 -0
  157. data/spec/shoes/rect_spec.rb +39 -0
  158. data/spec/shoes/renamed_delegate_spec.rb +70 -0
  159. data/spec/shoes/shape_spec.rb +106 -0
  160. data/spec/shoes/shared_examples/button.rb +6 -0
  161. data/spec/shoes/shared_examples/changeable.rb +26 -0
  162. data/spec/shoes/shared_examples/clickable.rb +5 -0
  163. data/spec/shoes/shared_examples/common_methods.rb +35 -0
  164. data/spec/shoes/shared_examples/dimensions.rb +32 -0
  165. data/spec/shoes/shared_examples/dsl.rb +44 -0
  166. data/spec/shoes/shared_examples/dsl/animate.rb +29 -0
  167. data/spec/shoes/shared_examples/dsl/arc.rb +45 -0
  168. data/spec/shoes/shared_examples/dsl/background.rb +26 -0
  169. data/spec/shoes/shared_examples/dsl/border.rb +10 -0
  170. data/spec/shoes/shared_examples/dsl/button.rb +5 -0
  171. data/spec/shoes/shared_examples/dsl/cap.rb +6 -0
  172. data/spec/shoes/shared_examples/dsl/check.rb +11 -0
  173. data/spec/shoes/shared_examples/dsl/edit_box.rb +8 -0
  174. data/spec/shoes/shared_examples/dsl/edit_line.rb +8 -0
  175. data/spec/shoes/shared_examples/dsl/editable_element.rb +29 -0
  176. data/spec/shoes/shared_examples/dsl/fill.rb +27 -0
  177. data/spec/shoes/shared_examples/dsl/flow.rb +15 -0
  178. data/spec/shoes/shared_examples/dsl/gradient.rb +62 -0
  179. data/spec/shoes/shared_examples/dsl/image.rb +21 -0
  180. data/spec/shoes/shared_examples/dsl/line.rb +9 -0
  181. data/spec/shoes/shared_examples/dsl/nofill.rb +6 -0
  182. data/spec/shoes/shared_examples/dsl/nostroke.rb +6 -0
  183. data/spec/shoes/shared_examples/dsl/oval.rb +88 -0
  184. data/spec/shoes/shared_examples/dsl/pattern.rb +34 -0
  185. data/spec/shoes/shared_examples/dsl/progress.rb +7 -0
  186. data/spec/shoes/shared_examples/dsl/rect.rb +92 -0
  187. data/spec/shoes/shared_examples/dsl/rgb.rb +26 -0
  188. data/spec/shoes/shared_examples/dsl/shape.rb +57 -0
  189. data/spec/shoes/shared_examples/dsl/star.rb +111 -0
  190. data/spec/shoes/shared_examples/dsl/stroke.rb +30 -0
  191. data/spec/shoes/shared_examples/dsl/strokewidth.rb +19 -0
  192. data/spec/shoes/shared_examples/dsl/style.rb +32 -0
  193. data/spec/shoes/shared_examples/dsl/text_elements.rb +81 -0
  194. data/spec/shoes/shared_examples/dsl/video.rb +5 -0
  195. data/spec/shoes/shared_examples/dsl_app_context.rb +8 -0
  196. data/spec/shoes/shared_examples/hover_leave.rb +11 -0
  197. data/spec/shoes/shared_examples/parent.rb +6 -0
  198. data/spec/shoes/shared_examples/scroll.rb +41 -0
  199. data/spec/shoes/shared_examples/shared_element_method.rb +60 -0
  200. data/spec/shoes/shared_examples/slot.rb +394 -0
  201. data/spec/shoes/shared_examples/state.rb +19 -0
  202. data/spec/shoes/shared_examples/style.rb +82 -0
  203. data/spec/shoes/slot_spec.rb +186 -0
  204. data/spec/shoes/sound_spec.rb +15 -0
  205. data/spec/shoes/span_spec.rb +112 -0
  206. data/spec/shoes/spec_helper.rb +24 -0
  207. data/spec/shoes/stack_spec.rb +79 -0
  208. data/spec/shoes/star_spec.rb +48 -0
  209. data/spec/shoes/text_block_dimensions_spec.rb +75 -0
  210. data/spec/shoes/text_block_spec.rb +270 -0
  211. data/spec/shoes/url_spec.rb +68 -0
  212. data/spec/shoes/widget_spec.rb +70 -0
  213. data/spec/shoes_spec.rb +44 -0
  214. data/spec/spec_helper.rb +19 -0
  215. data/static/downloading.png +0 -0
  216. data/static/shoes-icon-blue.png +0 -0
  217. data/static/shoes-icon-brown.png +0 -0
  218. data/static/shoes-icon.png +0 -0
  219. metadata +366 -0
@@ -0,0 +1,111 @@
1
+ shared_examples_for "star DSL method" do
2
+ it "creates a Shoes::Star" do
3
+ expect(dsl.star(30, 20)).to be_an_instance_of(Shoes::Star)
4
+ end
5
+
6
+ it "raises an ArgumentError with just one argument" do
7
+ expect { dsl.star(30) }.to raise_error(ArgumentError)
8
+ end
9
+
10
+ describe 'instantiation' do
11
+ let(:left) {10}
12
+ let(:top) {20}
13
+ let(:points) {15}
14
+ let(:outer) {27}
15
+ let(:inner) {33}
16
+ let(:clickable) { proc { } }
17
+
18
+ DEFAULT_POINTS = 10
19
+ DEFAULT_OUTER = 100.0
20
+ DEFAULT_INNER = 50.0
21
+
22
+ describe '2 arguments' do
23
+ subject {dsl.star left, top}
24
+ its(:left) {should eq left}
25
+ its(:top) {should eq top}
26
+ its(:points) {should eq DEFAULT_POINTS}
27
+ its(:outer) {should eq DEFAULT_OUTER}
28
+ its(:inner) {should eq DEFAULT_INNER}
29
+ end
30
+
31
+ describe '2 arguments with hash' do
32
+ subject { dsl.star left, top, click: clickable }
33
+ its(:left) {should eq left}
34
+ its(:top) {should eq top}
35
+ its(:points) {should eq DEFAULT_POINTS}
36
+ its(:outer) {should eq DEFAULT_OUTER}
37
+ its(:inner) {should eq DEFAULT_INNER}
38
+
39
+ it "gets the click" do
40
+ expect(subject.style[:click]).to eq(clickable)
41
+ end
42
+ end
43
+
44
+ describe '3 arguments with hash' do
45
+ subject { dsl.star left, top, points, click: clickable }
46
+ its(:left) {should eq left}
47
+ its(:top) {should eq top}
48
+ its(:points) {should eq points}
49
+ its(:outer) {should eq DEFAULT_OUTER}
50
+ its(:inner) {should eq DEFAULT_INNER}
51
+
52
+ it "gets the click" do
53
+ expect(subject.style[:click]).to eq(clickable)
54
+ end
55
+ end
56
+
57
+ describe '4 arguments' do
58
+ subject {dsl.star left, top, points, outer}
59
+ its(:left) {should eq left}
60
+ its(:top) {should eq top}
61
+ its(:points) {should eq points}
62
+ its(:outer) {should eq outer}
63
+ its(:inner) {should eq DEFAULT_INNER}
64
+ end
65
+
66
+ describe '4 arguments with hash' do
67
+ subject { dsl.star left, top, points, outer, click: clickable }
68
+ its(:left) {should eq left}
69
+ its(:top) {should eq top}
70
+ its(:points) {should eq points}
71
+ its(:outer) {should eq outer}
72
+ its(:inner) {should eq DEFAULT_INNER}
73
+
74
+ it "gets the click" do
75
+ expect(subject.style[:click]).to eq(clickable)
76
+ end
77
+ end
78
+
79
+ describe '5 arguments' do
80
+ subject {dsl.star left, top, points, outer, inner}
81
+ its(:left) {should eq left}
82
+ its(:top) {should eq top}
83
+ its(:points) {should eq points}
84
+ its(:outer) {should eq outer}
85
+ its(:inner) {should eq inner}
86
+ end
87
+
88
+ describe '5 arguments with hash' do
89
+ subject { dsl.star left, top, points, outer, inner, click: clickable }
90
+ its(:left) {should eq left}
91
+ its(:top) {should eq top}
92
+ its(:points) {should eq points}
93
+ its(:outer) {should eq outer}
94
+ its(:inner) {should eq inner}
95
+
96
+ it "gets the click" do
97
+ expect(subject.style[:click]).to eq(clickable)
98
+ end
99
+ end
100
+
101
+ describe 'too many arguments' do
102
+ oops = 1000
103
+ subject { dsl.star left, top, points, outer, inner, oops }
104
+
105
+ it "raises on construction" do
106
+ expect { subject }.to raise_error(ArgumentError)
107
+ end
108
+ end
109
+
110
+ end
111
+ end
@@ -0,0 +1,30 @@
1
+ shared_examples_for "stroke DSL method" do
2
+ let(:color) { Shoes::COLORS.fetch :tomato }
3
+
4
+ it "returns a color" do
5
+ expect(dsl.stroke(color).class).to eq(Shoes::Color)
6
+ end
7
+
8
+ # This works differently on a container than on a normal element
9
+ it "sets on receiver" do
10
+ dsl.stroke color
11
+ expect(dsl.style[:stroke]).to eq(color)
12
+ end
13
+
14
+ it "applies to subsequently created objects" do
15
+ dsl.stroke color
16
+ expect(Shoes::Rect).to receive(:new) do |*args|
17
+ style = args[-2]
18
+ expect(style[:stroke]).to eq(color)
19
+ end
20
+ dsl.rect(10, 10, 100, 100)
21
+ end
22
+
23
+ context "with hex string" do
24
+ let(:color) { "#fff" }
25
+
26
+ it "sets the color" do
27
+ expect(dsl.stroke(color)).to eq(Shoes::COLORS[:white])
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ shared_examples_for "strokewidth DSL method" do
2
+ it "returns a number" do
3
+ expect(dsl.strokewidth(4)).to eq(4)
4
+ end
5
+
6
+ it "sets on receiver" do
7
+ dsl.strokewidth 4
8
+ expect(dsl.style[:strokewidth]).to eq(4)
9
+ end
10
+
11
+ it "applies to subsequently created objects" do
12
+ dsl.strokewidth 6
13
+ expect(Shoes::Rect).to receive(:new) do |*args|
14
+ style = args[-2]
15
+ expect(style[:strokewidth]).to eq(6)
16
+ end
17
+ dsl.rect(10, 10, 100, 100)
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ shared_examples_for "style DSL method" do
2
+ describe "setting new defaults for text block" do
3
+ let(:stroke) { Shoes::COLORS[:chartreuse] }
4
+ let(:size) { 42 }
5
+ let(:fill) { Shoes::COLORS[:peru] }
6
+ let(:font ) { "SOME FONT" }
7
+ let(:style) { {:stroke => stroke, :size => size, :fill => fill, :font => font} }
8
+
9
+ %w(Banner Title Subtitle Tagline Caption Para Inscription).each do |text_block|
10
+ describe text_block do
11
+ let(:element) { dsl.public_send text_block.downcase, "Hello!" }
12
+ let(:klass) { Shoes.const_get(text_block) }
13
+
14
+ before :each do
15
+ dsl.style klass, style
16
+ end
17
+
18
+ it "creates element with appropriate class" do
19
+ expect(element.class).to eq(klass)
20
+ end
21
+
22
+ it "sets size" do
23
+ expect(element.size).to eq(size)
24
+ end
25
+
26
+ it "sets font" do
27
+ expect(element.font).to eq(font)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,81 @@
1
+ shared_examples_for "text element DSL methods" do
2
+ it "should set banner font size to 48" do
3
+ text_block = dsl.banner("hello!")
4
+ expect(text_block.size).to eql 48
5
+ end
6
+
7
+ it "should set title font size to 34" do
8
+ text_block = dsl.title("hello!")
9
+ expect(text_block.size).to eql 34
10
+ end
11
+
12
+ it "should set subtitle font size to 26" do
13
+ text_block = dsl.subtitle("hello!")
14
+ expect(text_block.size).to eql 26
15
+ end
16
+
17
+ it "should set tagline font size to 18" do
18
+ text_block = dsl.tagline("hello!")
19
+ expect(text_block.size).to eql 18
20
+ end
21
+
22
+ it "should set caption font size to 14" do
23
+ text_block = dsl.caption("hello!")
24
+ expect(text_block.size).to eql 14
25
+ end
26
+
27
+ it "should set para font size to 12" do
28
+ text_block = dsl.para("hello!")
29
+ expect(text_block.size).to eql 12
30
+ end
31
+
32
+ it "should set inscription font size to 10" do
33
+ text_block = dsl.inscription("hello!")
34
+ expect(text_block.size).to eql 10
35
+ end
36
+
37
+ describe 'span' do
38
+ it 'should parse the color' do
39
+ span = dsl.span 'Hello', stroke: '#ccc'
40
+ expect(span.style[:stroke]).to eq Shoes::Color.new 204, 204, 204
41
+ end
42
+
43
+ it 'should handle a splatted array of links' do
44
+ expect{dsl.span *[dsl.link('foo'), dsl.link('foo')]}.not_to raise_error
45
+ end
46
+
47
+ it 'should handle a splatted array of links and parse the color' do
48
+ span = dsl.span *[dsl.link('foo'), dsl.link('foo')], stroke: '#ccc'
49
+ expect(span.style[:stroke]).to eq Shoes::Color.new 204, 204, 204
50
+ end
51
+
52
+ it 'should handle a splatted array of links with a block' do
53
+ link = dsl.link('foo') { "Bar" }
54
+ expect{dsl.span *[link, link]}.not_to raise_error
55
+ end
56
+ end
57
+
58
+ describe 'link' do
59
+ it 'handles multiple texts' do
60
+ link = dsl.link('one', 'two')
61
+ expect(link.to_s).to eql('onetwo')
62
+ end
63
+
64
+ it 'handles trailing options' do
65
+ link = dsl.link('one', 'two', stroke: '#ccc')
66
+ expect(link.to_s).to eql('onetwo')
67
+ expect(link.style[:stroke]).to eq Shoes::Color.new 204, 204, 204
68
+ end
69
+ end
70
+
71
+ describe 'para' do
72
+ context "with nested text fragments with parameters" do
73
+ Shoes::DSL::TEXT_STYLES.keys.each do |style|
74
+ it "handles opts properly for #{style}" do
75
+ para = dsl.para(dsl.send(style, style, stroke: '#ccc'))
76
+ expect(para.text).to eq(style.to_s)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,5 @@
1
+ shared_examples_for 'video DSL method' do
2
+ it 'throws a Shoes::NotImplementedError' do
3
+ expect{dsl.video}.to raise_error Shoes::NotImplementedError
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ shared_context "dsl app" do
2
+ let(:input_block) { Proc.new {} }
3
+ let(:input_opts) { Hash.new }
4
+ let(:user_facing_app) { Shoes::App.new input_opts, &input_block }
5
+ let(:app) { user_facing_app.instance_variable_get(:@__app__) }
6
+ let(:parent) { Shoes::Flow.new app, app }
7
+ end
8
+
@@ -0,0 +1,11 @@
1
+ shared_examples "hover and leave events" do
2
+ let(:proc) {Proc.new do end}
3
+
4
+ it 'can execute hover without raising an error' do
5
+ expect{subject.hover proc}.not_to raise_error
6
+ end
7
+
8
+ it 'can execute leave without raising an error' do
9
+ expect{subject.leave proc}.not_to raise_error
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ # requires you to provide a let(:parent)
2
+ shared_examples_for 'object with parent' do
3
+ it 'has a getter for the parent' do
4
+ expect(subject.parent).to eq parent
5
+ end
6
+ end
@@ -0,0 +1,41 @@
1
+ shared_examples_for "scrollable slot" do
2
+ its(:scroll) { should be_truthy }
3
+ it "initializes scroll_top to 0" do
4
+ expect(subject.scroll_top).to eq(0)
5
+ end
6
+ end
7
+
8
+ shared_examples_for "scrollable slot with overflowing content" do
9
+ it "retains the same height" do
10
+ expect(subject.height).to eq(height)
11
+ end
12
+
13
+ it "has scroll_height larger than height" do
14
+ expect(subject.scroll_height).to be > height
15
+ end
16
+
17
+ it "has scroll_max = (scroll_height - height)" do
18
+ expect(subject.scroll_max).to eq(subject.scroll_height - subject.height)
19
+ end
20
+
21
+ it 'adjusts scroll_top' do
22
+ expect(subject.scroll_top).to eq(new_position)
23
+ end
24
+ end
25
+
26
+ shared_context "scroll" do
27
+ let(:height) { 200 }
28
+ let(:input_opts) { {left: 40, top: 20, width: 400, height: height} }
29
+ let(:opts) { input_opts.merge(scroll: scroll) }
30
+ end
31
+
32
+ shared_context "overflowing content" do
33
+ let(:new_position) { 300 }
34
+
35
+ before :each do
36
+ 200.times do
37
+ Shoes::TextBlock.new(app, subject, "Fourteen fat chimichangas", size: 18)
38
+ end
39
+ subject.scroll_top = new_position
40
+ end
41
+ end
@@ -0,0 +1,60 @@
1
+ require 'shoes/color'
2
+
3
+ shared_examples_for "object with stroke" do
4
+ let(:color) { Shoes::COLORS.fetch :tomato }
5
+ let(:color2) { Shoes::COLORS.fetch :forestgreen }
6
+ let(:gradient) { Shoes::Gradient.new(color, color2) }
7
+
8
+ specify "returns a color" do
9
+ c = subject.stroke = color
10
+ expect(c.class).to eq(Shoes::Color)
11
+ end
12
+
13
+ specify "sets on receiver" do
14
+ subject.stroke = color
15
+ expect(subject.stroke).to eq(color)
16
+ expect(subject.style[:stroke]).to eq(color)
17
+ end
18
+
19
+ specify "sets with a gradient" do
20
+ subject.stroke = gradient
21
+ expect(subject.stroke).to eq(gradient)
22
+ expect(subject.style[:stroke]).to eq(gradient)
23
+ end
24
+
25
+ # Be sure the subject does *not* have the stroke set previously
26
+ specify "defaults to black" do
27
+ expect(subject.stroke).to eq(Shoes::COLORS.fetch :black)
28
+ end
29
+
30
+ describe "strokewidth" do
31
+ specify "defaults to 1" do
32
+ expect(subject.strokewidth).to eq(1)
33
+ end
34
+
35
+ specify "sets" do
36
+ subject.strokewidth = 2
37
+ expect(subject.strokewidth).to eq(2)
38
+ end
39
+ end
40
+ end
41
+
42
+ shared_examples_for "object with fill" do
43
+ let(:color) { Shoes::COLORS.fetch :honeydew }
44
+
45
+ specify "returns a color" do
46
+ c = subject.fill = color
47
+ expect(c.class).to eq(Shoes::Color)
48
+ end
49
+
50
+ specify "sets on receiver" do
51
+ subject.fill = color
52
+ expect(subject.fill).to eq(color)
53
+ expect(subject.style[:fill]).to eq(color)
54
+ end
55
+
56
+ # Be sure the subject does *not* have the stroke set previously
57
+ specify "defaults to black" do
58
+ expect(subject.fill).to eq(Shoes::COLORS.fetch :black)
59
+ end
60
+ end
@@ -0,0 +1,394 @@
1
+ shared_examples_for "Slot" do
2
+ it "should be able to append" do
3
+ expect(subject.contents).to be_empty
4
+ our_subject = subject
5
+ app.execute_block Proc.new { our_subject.append {para "foo"} }
6
+ expect(subject.contents.size).to eq(1)
7
+ end
8
+
9
+ it 'has a height of 0 as it is empty although it has a top' do
10
+ subject.absolute_top = 100
11
+ subject.contents_alignment
12
+ expect(subject.height).to eq 0
13
+ end
14
+
15
+ it_behaves_like 'prepending'
16
+ it_behaves_like 'clearing'
17
+ it_behaves_like 'element one positioned with bottom and right'
18
+ it_behaves_like 'growing although relatively positioned elements'
19
+ it_behaves_like 'margin and positioning'
20
+ it_behaves_like 'margin with a relative positioned child'
21
+ end
22
+
23
+ shared_context 'one slot child' do
24
+ let(:ele_opts) {Hash.new}
25
+ let(:element) {Shoes::FakeElement.new(nil, {height: 100,width: 50}.merge(ele_opts))}
26
+
27
+ before :each do
28
+ subject.add_child element
29
+ end
30
+ end
31
+
32
+ shared_context 'two slot children' do
33
+ include_context 'one slot child'
34
+ let(:element2) {Shoes::FakeElement.new nil, height: 200, width: 70}
35
+
36
+ before :each do
37
+ subject.add_child element2
38
+ end
39
+ end
40
+
41
+ shared_context 'hidden child' do
42
+ let(:hidden_element) {Shoes::FakeElement.new nil, height: 200, width: 70}
43
+
44
+ before :each do
45
+ subject.add_child hidden_element
46
+ hidden_element.gui = double("hidden gui", update_visibility: nil)
47
+ hidden_element.hide
48
+ end
49
+ end
50
+
51
+ shared_context 'three slot children' do
52
+ include_context 'two slot children'
53
+ let(:element3) {Shoes::FakeElement.new(nil, height: 50, width: 20)}
54
+
55
+ before :each do
56
+ subject.add_child element3
57
+ end
58
+ end
59
+
60
+ shared_context 'contents_alignment' do
61
+ before :each do
62
+ subject.contents_alignment
63
+ end
64
+ end
65
+
66
+ shared_context 'element one with top and left' do
67
+ let(:ele_top) {22}
68
+ let(:ele_left) {47}
69
+ let(:ele_opts) {{left: ele_left, top: ele_top}}
70
+ end
71
+
72
+ shared_context 'slot with set height and width' do
73
+ let(:input_opts) {{width: 250, height: 300}}
74
+ end
75
+
76
+ shared_context 'slot with a top margin' do
77
+ let(:margin_top) {70}
78
+ let(:input_opts) {{margin_top: margin_top}}
79
+ end
80
+
81
+ shared_context 'slot with a left margin' do
82
+ let(:margin_left) {30}
83
+ let(:input_opts) {{margin_left: margin_left}}
84
+ end
85
+
86
+ shared_context 'element one with bottom and right' do
87
+ let(:ele_bottom) {24}
88
+ let(:ele_right) {49}
89
+ let(:ele_opts) {{right: ele_right, bottom: ele_bottom}}
90
+ end
91
+
92
+ shared_examples_for 'positioning through :_position' do
93
+
94
+ let(:element) {Shoes::FakeElement.new nil, height: 100, width: 50}
95
+
96
+ def add_child_and_align
97
+ subject.add_child element
98
+ subject.contents_alignment
99
+ end
100
+
101
+ it 'sends the child the :_position method to position it' do
102
+ expect(element).to receive(:_position).and_call_original
103
+ add_child_and_align
104
+ end
105
+
106
+ it 'does not send _position again if the position did not change' do
107
+ add_child_and_align
108
+ expect(element).not_to receive(:_position)
109
+ subject.contents_alignment
110
+ end
111
+ end
112
+
113
+ shared_examples_for 'element one positioned with top and left' do
114
+ it 'positions the element at its left value' do
115
+ expect(element.absolute_left).to eq subject.absolute_left + ele_left
116
+ end
117
+
118
+ it 'positions the element at its top value' do
119
+ expect(element.absolute_top).to eq subject.absolute_top + ele_top
120
+ end
121
+ end
122
+
123
+ shared_examples_for 'element one positioned with bottom and right' do
124
+ include_context 'one slot child'
125
+ include_context 'contents_alignment'
126
+ include_context 'element one with bottom and right'
127
+ include_context 'slot with set height and width'
128
+
129
+ it 'positions the element from its right' do
130
+ expect(element.absolute_right).to eq (subject.absolute_right - ele_right - 1)
131
+ end
132
+
133
+ it 'positions the element from its bottom' do
134
+ expect(element.absolute_bottom).to eq (subject.absolute_bottom - ele_bottom - 1)
135
+ end
136
+ end
137
+
138
+ shared_examples_for 'positions the first element in the top left' do
139
+ include_context 'one slot child'
140
+ include_context 'contents_alignment'
141
+ it 'positions a single object at the same top as self' do
142
+ expect(element.absolute_top).to eq subject.element_top
143
+ end
144
+
145
+ it 'positions a single object at the same left as self' do
146
+ expect(element.absolute_left).to eq subject.element_left
147
+ end
148
+
149
+ it 'has a slot height of the element height' do
150
+ expect(subject.height).to eq element.height
151
+ end
152
+
153
+ describe 'top and left' do
154
+ include_context 'element one with top and left'
155
+ it_behaves_like 'element one positioned with top and left'
156
+ end
157
+ end
158
+
159
+ shared_examples_for 'arranges elements underneath each other' do
160
+ include_context 'two slot children'
161
+ include_context 'contents_alignment'
162
+
163
+ it 'positions an element beneath a previous element' do
164
+ expect(element2.absolute_top).to eq element.absolute_bottom + 1
165
+ end
166
+
167
+ it 'still positions it at the start of the line (e.g. self.left)' do
168
+ expect(element2.absolute_left).to eq subject.absolute_left
169
+ end
170
+
171
+ it 'has a stack height according to its contents' do
172
+ expect(subject.height).to eq (element.height + element2.height)
173
+ end
174
+
175
+ it 'has an absolute_bottom of top + height' do
176
+ expect(subject.absolute_bottom).to eq (subject.absolute_top + subject.height - 1)
177
+ end
178
+
179
+ describe 'element one with top and left' do
180
+ include_context 'element one with top and left'
181
+ it_behaves_like 'element one positioned with top and left'
182
+
183
+ describe 'positions element2 disregarding element1' do
184
+ it 'has the same absolute left as the slot' do
185
+ expect(element2.absolute_left).to eq subject.absolute_left
186
+ end
187
+
188
+ it 'has the same absolute top as the slot' do
189
+ expect(element2.absolute_top).to eq subject.absolute_top
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ shared_examples_for 'set height and contents alignment' do
196
+ include_context 'two slot children'
197
+
198
+ it 'contents_alignment returns the height of the content' do
199
+ expect(subject.contents_alignment).to eq (element.height + element2.height)
200
+ end
201
+
202
+ it 'still has the same height though' do
203
+ old_height = subject.height
204
+ subject.contents_alignment
205
+ expect(subject.height).to eq old_height
206
+ end
207
+ end
208
+
209
+ shared_examples_for 'taking care of margin' do
210
+ include_context 'two slot children'
211
+ include_context 'contents_alignment'
212
+
213
+ it 'respects the left margin for the first element' do
214
+ expect(element.absolute_left).to eq input_opts[:margin]
215
+ end
216
+
217
+ it 'respects the left margin for the second element' do
218
+ expect(element2.absolute_left).to eq input_opts[:margin]
219
+ end
220
+
221
+ it 'respects the top margin for the first element' do
222
+ expect(element.absolute_top).to eq input_opts[:margin]
223
+ end
224
+ end
225
+
226
+ shared_examples_for 'growing although relatively positioned elements' do
227
+ include_context 'one slot child'
228
+ include_context 'contents_alignment'
229
+
230
+ describe 'positioned at the very beginning' do
231
+ let(:ele_opts) {{top: 0}}
232
+
233
+ it 'grows the slot height' do
234
+ expect(subject.height).to eq element.height
235
+ end
236
+ end
237
+
238
+ describe 'positioned with a good offset' do
239
+ let(:ele_opts) {{top: 70}}
240
+
241
+ it 'grows the height even further' do
242
+ expect(subject.height).to eq element.height + 70
243
+ end
244
+ end
245
+
246
+ describe 'positioning with hidden elements' do
247
+ include_context 'hidden child'
248
+
249
+ it 'grows only to height of first child' do
250
+ subject.contents_alignment
251
+ expect(subject.height).to eq element.height
252
+ end
253
+ end
254
+ end
255
+
256
+ shared_examples_for 'prepending' do
257
+ include_context 'two slot children'
258
+ let(:prepend1) {double 'prepend1'}
259
+ let(:prepend2) {double 'prepend2'}
260
+
261
+ describe 'one element' do
262
+ before :each do
263
+ subject.prepend do
264
+ subject.add_child prepend1
265
+ end
266
+ end
267
+
268
+ it 'as the first' do
269
+ expect(subject.contents.first).to eq prepend1
270
+ end
271
+
272
+ it 'has a total of 3 elements then' do
273
+ expect(subject.contents.size).to eq(3)
274
+ end
275
+ end
276
+
277
+ describe 'two elements' do
278
+ before :each do
279
+ subject.prepend do
280
+ subject.add_child prepend1
281
+ subject.add_child prepend2
282
+ end
283
+ end
284
+
285
+ it 'has prepend1 as the first child' do
286
+ expect(subject.contents.first).to eq prepend1
287
+ end
288
+
289
+ it 'has prepend2 as the second child' do
290
+ expect(subject.contents[1]).to eq prepend2
291
+ end
292
+
293
+ it 'has a total of 4 children' do
294
+ expect(subject.contents.size).to eq(4)
295
+ end
296
+ end
297
+
298
+ describe 'two times' do
299
+ before :each do
300
+ subject.prepend { subject.add_child prepend1 }
301
+ subject.prepend {subject.add_child prepend2 }
302
+ end
303
+
304
+ it 'has the last prepended element as the first' do
305
+ expect(subject.contents.first).to eq prepend2
306
+ end
307
+
308
+ it 'has the first prepended element as the second' do
309
+ expect(subject.contents[1]).to eq prepend1
310
+ end
311
+
312
+ it 'has a total of 4 children' do
313
+ expect(subject.contents.size).to eq(4)
314
+ end
315
+ end
316
+ end
317
+
318
+ shared_examples_for 'clearing' do
319
+ include_context 'two slot children'
320
+
321
+ describe '#clear' do
322
+ it 'removes all contents' do
323
+ subject.clear
324
+ expect(subject.contents).to be_empty
325
+ end
326
+ end
327
+
328
+ describe 'Element#remove' do
329
+ it 'removes the element' do
330
+ element.parent = subject
331
+ element.remove
332
+ expect(subject.contents).not_to include element
333
+ end
334
+ end
335
+ end
336
+
337
+ shared_examples_for 'margin with a relative positioned child' do
338
+ include_context 'one slot child'
339
+ include_context 'element one with top and left'
340
+ include_context 'contents_alignment'
341
+
342
+ describe 'margin top' do
343
+ include_context 'slot with a top margin'
344
+
345
+ it 'positions the first element taking the top margin into account' do
346
+ expect(element.absolute_top).to eq ele_top + margin_top
347
+ end
348
+
349
+ it 'still keeps the left value intact (only margin_top)' do
350
+ expect(element.absolute_left).to eq ele_left
351
+ end
352
+ end
353
+
354
+ describe 'left margin' do
355
+ include_context 'slot with a left margin'
356
+
357
+ it 'positions the element to take the left margin into account' do
358
+ expect(element.absolute_left).to eq ele_left + margin_left
359
+ end
360
+
361
+ it 'keeps the top margin intact' do
362
+ expect(element.absolute_top).to eq ele_top
363
+ end
364
+ end
365
+ end
366
+
367
+ shared_examples_for 'margin and positioning' do
368
+ include_context 'one slot child'
369
+ include_context 'contents_alignment'
370
+
371
+ describe 'margin top' do
372
+ include_context 'slot with a top margin'
373
+
374
+ it 'positions the element after margin_top' do
375
+ expect(element.absolute_top).to eq margin_top
376
+ end
377
+
378
+ it 'leaves the left value as zero' do
379
+ expect(element.absolute_left).to eq 0
380
+ end
381
+ end
382
+
383
+ describe 'margin left' do
384
+ include_context 'slot with a left margin'
385
+
386
+ it 'positions the element after margin_left' do
387
+ expect(element.absolute_left).to eq margin_left
388
+ end
389
+
390
+ it 'leaves the top value as zero' do
391
+ expect(element.absolute_top).to eq 0
392
+ end
393
+ end
394
+ end