under-os-ui 1.4.0

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 (104) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +26 -0
  3. data/lib/assets/fontawesome-webfont.ttf +0 -0
  4. data/lib/assets/under-os.css +115 -0
  5. data/lib/core/kernel.rb +16 -0
  6. data/lib/under-os-ui.rb +6 -0
  7. data/lib/under_os/app.rb +26 -0
  8. data/lib/under_os/config.rb +25 -0
  9. data/lib/under_os/history.rb +53 -0
  10. data/lib/under_os/page.rb +178 -0
  11. data/lib/under_os/page/builder.rb +96 -0
  12. data/lib/under_os/page/layout.rb +43 -0
  13. data/lib/under_os/page/matcher.rb +128 -0
  14. data/lib/under_os/page/stylesheet.rb +67 -0
  15. data/lib/under_os/parser.rb +24 -0
  16. data/lib/under_os/parser/css.rb +37 -0
  17. data/lib/under_os/parser/html.rb +97 -0
  18. data/lib/under_os/ui.rb +3 -0
  19. data/lib/under_os/ui/alert.rb +52 -0
  20. data/lib/under_os/ui/button.rb +42 -0
  21. data/lib/under_os/ui/collection.rb +65 -0
  22. data/lib/under_os/ui/collection/cell.rb +21 -0
  23. data/lib/under_os/ui/collection/delegate.rb +70 -0
  24. data/lib/under_os/ui/collection/item.rb +32 -0
  25. data/lib/under_os/ui/collection/layout.rb +43 -0
  26. data/lib/under_os/ui/collection/styles.rb +15 -0
  27. data/lib/under_os/ui/div.rb +3 -0
  28. data/lib/under_os/ui/form.rb +60 -0
  29. data/lib/under_os/ui/icon.rb +61 -0
  30. data/lib/under_os/ui/icon/awesome.rb +376 -0
  31. data/lib/under_os/ui/icon/engine.rb +9 -0
  32. data/lib/under_os/ui/image.rb +31 -0
  33. data/lib/under_os/ui/input.rb +140 -0
  34. data/lib/under_os/ui/label.rb +21 -0
  35. data/lib/under_os/ui/locker.rb +42 -0
  36. data/lib/under_os/ui/navbar.rb +123 -0
  37. data/lib/under_os/ui/progress.rb +17 -0
  38. data/lib/under_os/ui/scroll.rb +102 -0
  39. data/lib/under_os/ui/select.rb +95 -0
  40. data/lib/under_os/ui/sidebar.rb +45 -0
  41. data/lib/under_os/ui/slider.rb +37 -0
  42. data/lib/under_os/ui/spinner.rb +23 -0
  43. data/lib/under_os/ui/style.rb +21 -0
  44. data/lib/under_os/ui/style/fonts.rb +56 -0
  45. data/lib/under_os/ui/style/margins.rb +164 -0
  46. data/lib/under_os/ui/style/outlining.rb +170 -0
  47. data/lib/under_os/ui/style/positioning.rb +183 -0
  48. data/lib/under_os/ui/switch.rb +26 -0
  49. data/lib/under_os/ui/textarea.rb +19 -0
  50. data/lib/under_os/ui/utils/animation.rb +101 -0
  51. data/lib/under_os/ui/utils/commons.rb +70 -0
  52. data/lib/under_os/ui/utils/dimensions.rb +37 -0
  53. data/lib/under_os/ui/utils/events.rb +210 -0
  54. data/lib/under_os/ui/utils/manipulation.rb +44 -0
  55. data/lib/under_os/ui/utils/position.rb +21 -0
  56. data/lib/under_os/ui/utils/size.rb +21 -0
  57. data/lib/under_os/ui/utils/styles.rb +89 -0
  58. data/lib/under_os/ui/utils/traversing.rb +44 -0
  59. data/lib/under_os/ui/utils/wrap.rb +77 -0
  60. data/lib/under_os/ui/view.rb +31 -0
  61. data/spec/assets/app.css +13 -0
  62. data/spec/assets/test.css +7 -0
  63. data/spec/assets/test.html +3 -0
  64. data/spec/assets/test.png +0 -0
  65. data/spec/assets/test_page.rb +2 -0
  66. data/spec/under_os/page/builder_spec.rb +128 -0
  67. data/spec/under_os/page/layout_spec.rb +18 -0
  68. data/spec/under_os/page/matcher_spec.rb +260 -0
  69. data/spec/under_os/page/stylesheet_spec.rb +83 -0
  70. data/spec/under_os/page_spec.rb +5 -0
  71. data/spec/under_os/parser/css_spec.rb +77 -0
  72. data/spec/under_os/parser/html_spec.rb +152 -0
  73. data/spec/under_os/parser_spec.rb +16 -0
  74. data/spec/under_os/ui/button_spec.rb +50 -0
  75. data/spec/under_os/ui/collection_spec.rb +19 -0
  76. data/spec/under_os/ui/div_spec.rb +24 -0
  77. data/spec/under_os/ui/form_spec.rb +156 -0
  78. data/spec/under_os/ui/icon_spec.rb +57 -0
  79. data/spec/under_os/ui/image_spec.rb +39 -0
  80. data/spec/under_os/ui/input_spec.rb +109 -0
  81. data/spec/under_os/ui/label_spec.rb +22 -0
  82. data/spec/under_os/ui/locker_spec.rb +31 -0
  83. data/spec/under_os/ui/progress_spec.rb +31 -0
  84. data/spec/under_os/ui/scroll_spec.rb +75 -0
  85. data/spec/under_os/ui/select_spec.rb +135 -0
  86. data/spec/under_os/ui/sidebar_spec.rb +35 -0
  87. data/spec/under_os/ui/slider_spec.rb +69 -0
  88. data/spec/under_os/ui/spinner_spec.rb +57 -0
  89. data/spec/under_os/ui/style/fonts_spec.rb +111 -0
  90. data/spec/under_os/ui/style/margins_spec.rb +106 -0
  91. data/spec/under_os/ui/style/outlining_spec.rb +101 -0
  92. data/spec/under_os/ui/style/positioning_spec.rb +69 -0
  93. data/spec/under_os/ui/style_spec.rb +19 -0
  94. data/spec/under_os/ui/switch_spec.rb +60 -0
  95. data/spec/under_os/ui/textarea_spec.rb +34 -0
  96. data/spec/under_os/ui/utils/commons_spec.rb +81 -0
  97. data/spec/under_os/ui/utils/events_spec.rb +87 -0
  98. data/spec/under_os/ui/utils/manipulation_spec.rb +130 -0
  99. data/spec/under_os/ui/utils/styles_spec.rb +140 -0
  100. data/spec/under_os/ui/utils/traversing_spec.rb +124 -0
  101. data/spec/under_os/ui/utils/wrap_spec.rb +69 -0
  102. data/spec/under_os/ui/view_spec.rb +39 -0
  103. data/under-os-ui.gemspec +23 -0
  104. metadata +216 -0
@@ -0,0 +1,18 @@
1
+ describe UnderOs::Page::Layout do
2
+ before do
3
+ @page = TestPage.new
4
+ @layout = UnderOs::Page::Layout.new(@page)
5
+ end
6
+
7
+ it "should pickup the elements from the layout.html file" do
8
+ @page.view.should.not == nil
9
+ children = @page.view.children
10
+ children.size.should == 1
11
+ children[0].class.should == UnderOs::UI::Button
12
+ children[0].text.should == 'Say Hello'
13
+ end
14
+
15
+ it "should pickup the page title from the test layout" do
16
+ @page.title.should == 'Hello World'
17
+ end
18
+ end
@@ -0,0 +1,260 @@
1
+ describe UnderOs::Page::StylesMatcher do
2
+ before do
3
+ @view = UnderOs::UI::View.new
4
+ @view1 = UnderOs::UI::View.new
5
+ @view2 = UnderOs::UI::View.new
6
+ @matcher = UnderOs::Page::StylesMatcher.new('smth')
7
+ end
8
+
9
+ describe '.new' do
10
+ it "should cache instances" do
11
+ @i1 = UnderOs::Page::StylesMatcher.new('.one')
12
+ @i2 = UnderOs::Page::StylesMatcher.new('.one')
13
+ @i3 = UnderOs::Page::StylesMatcher.new('.two')
14
+
15
+ @i1.should.be.same_as @i2
16
+ @i1.should.not == @i3
17
+ end
18
+ end
19
+
20
+ describe '#match' do
21
+ it "should return 'true' for views with score > 0" do
22
+ def @matcher.score_for(view); 1 end
23
+ @matcher.match(@view).should == true
24
+ end
25
+
26
+ it "should return 'false' for views with score == 0" do
27
+ def @matcher.score_for(view); 0 end
28
+ @matcher.match(@view).should == false
29
+ end
30
+ end
31
+
32
+ describe '#score_for' do
33
+ def score_for(view, css_rule)
34
+ UnderOs::Page::StylesMatcher.new(css_rule).score_for(view)
35
+ end
36
+
37
+ describe 'tags matching' do
38
+ it "should add score for tag match" do
39
+ score_for(@view, 'view').should == 1
40
+ end
41
+
42
+ it "should not add score for not matching tags" do
43
+ score_for(@view, 'button').should == 0
44
+ end
45
+
46
+ it "should not add score if the id is wrong" do
47
+ score_for(@view, 'view#some-id').should == 0
48
+ end
49
+
50
+ it "should not add score if the css-rule is wrong" do
51
+ score_for(@view, 'view.some-class').should == 0
52
+ end
53
+
54
+ it "should handle the * as the tag name" do
55
+ score_for(@view, '*').should == 1
56
+ end
57
+ end
58
+
59
+ describe 'IDs matching' do
60
+ it "should add score for IDs matches" do
61
+ @view.id = 'my-id'
62
+ score_for(@view, '#my-id').should == 1
63
+ end
64
+
65
+ it "should not add score for mismatching IDs" do
66
+ @view.id = 'my-id'
67
+ score_for(@view, '#another-id').should == 0
68
+ end
69
+
70
+ it "should not crash if ID is missing" do
71
+ score_for(@view, 'button').should == 0
72
+ end
73
+
74
+ it "should not add points if the tag is different" do
75
+ @view.id = 'my-id'
76
+ score_for(@view, 'button#my-id').should == 0
77
+ end
78
+ end
79
+
80
+ describe 'className matching' do
81
+ it "should add score for matching class names" do
82
+ @view.className = 'my-class'
83
+ score_for(@view, '.my-class').should == 1
84
+ end
85
+
86
+ it "should not add score for mismatching class names" do
87
+ @view.className = 'my-class'
88
+ score_for(@view, '.another-class').should == 0
89
+ end
90
+
91
+ it "should add point for every matching class name" do
92
+ @view.className = 'class1 class2'
93
+ score_for(@view, '.class1.class2').should == 2
94
+ score_for(@view, '.class2.class1').should == 2
95
+ end
96
+
97
+ it "should not add points one of multiple classes don't match" do
98
+ @view.className = 'class1 class2'
99
+ score_for(@view, '.class1.class3').should == 0
100
+ score_for(@view, '.class3.class2').should == 0
101
+ end
102
+
103
+ it "should not add points if the tag is different" do
104
+ @view.className = 'my-class'
105
+ score_for(@view, 'button.my-class').should == 0
106
+ end
107
+
108
+ it "should not add points if the ID is different" do
109
+ @view.className = 'my-class'
110
+ score_for(@view, '#another-id.my-class').should == 0
111
+ end
112
+ end
113
+
114
+ describe "attribute matchers" do
115
+ before do
116
+ @view.id = "my-view"
117
+ end
118
+
119
+ def score_for(view, css_rule)
120
+ UnderOs::Page::StylesMatcher.new(css_rule).score_for(view)
121
+ end
122
+
123
+ describe "with the '=' operator" do
124
+ it "scores when the value matches exactly" do
125
+ score_for(@view, '[id="my-view"]').should == 1
126
+ end
127
+
128
+ it "doesn't count when the value does not match" do
129
+ score_for(@view, "[id='my']").should == 0
130
+ end
131
+ end
132
+
133
+ describe "with the '*=' operator" do
134
+ it "scores when the attribute includes the value" do
135
+ score_for(@view, '[id*=vie]').should == 1
136
+ end
137
+
138
+ it "doesn't count when the value doesn't match attribute" do
139
+ score_for(@view, '[id*=mismatch]').should == 0
140
+ end
141
+ end
142
+
143
+ describe "with the ^= operator" do
144
+ it "scores when the attribute starts with the value" do
145
+ score_for(@view, '[id^=my]').should == 1
146
+ end
147
+
148
+ it "doesn't count when the attribute doesn't start with the value" do
149
+ score_for(@view, '[id^=view]').should == 0
150
+ end
151
+ end
152
+
153
+ describe "with the $= operator" do
154
+ it "scores when the attribute ends with the value" do
155
+ score_for(@view, '[id$=view]').should == 1
156
+ end
157
+
158
+ it "doesn't count when the attribute doesn't ends with the value" do
159
+ score_for(@view, '[id$=my]').should == 0
160
+ end
161
+ end
162
+
163
+ describe "with the ~= operator" do
164
+ before { @view.id = "one two three" }
165
+
166
+ it "scores when the value is a token from the attribute" do
167
+ score_for(@view, '[id~=one]').should == 1
168
+ score_for(@view, '[id~=two]').should == 1
169
+ score_for(@view, '[id~=three]').should == 1
170
+ end
171
+
172
+ it "doesn't trigger on completely different strings" do
173
+ score_for(@view, '[id~=four]').should == 0
174
+ end
175
+
176
+ it "doesn't trigger on partial substrings" do
177
+ score_for(@view, '[id~=tw]').should == 0
178
+ end
179
+ end
180
+
181
+ describe "with the |= operator" do
182
+ it "scores when value is a dashed token of the attribute" do
183
+ score_for(@view, '[id|=my]').should == 1
184
+ score_for(@view, '[id|=view]').should == 1
185
+ end
186
+
187
+ it "doesn't trigger on completely different values" do
188
+ score_for(@view, '[id|=mismatch]').should == 0
189
+ end
190
+
191
+ it "doesn't trigger on partial matches" do
192
+ score_for(@view, '[id|=vie]').should == 0
193
+ end
194
+ end
195
+ end
196
+
197
+ describe 'multiple nested matches' do
198
+ it "should count in all the matches" do
199
+ @view.id = 'my-id'
200
+ @view.className = 'class1 class2'
201
+ score_for(@view, 'view#my-id.class1.class2').should == 4
202
+ end
203
+ end
204
+
205
+ describe 'in multi-leveled structures' do
206
+ before do
207
+ @v1 = UnderOs::UI::View.new(class: 'v1')
208
+ @v2 = UnderOs::UI::View.new(class: 'v2')
209
+ @v3 = UnderOs::UI::View.new(class: 'v3')
210
+ @v4 = UnderOs::UI::View.new(class: 'v4')
211
+
212
+ @v1.append(@v2.append(@v3.append(@v4.append(@view))))
213
+
214
+ @view.id = 'my-view'
215
+ end
216
+
217
+ it "should still match singular rules" do
218
+ score_for(@view, '#my-view').should == 1
219
+ end
220
+
221
+ it "should add points for matching parent" do
222
+ score_for(@view, '.v4 #my-view').should == 2
223
+ score_for(@view, 'view.v4 #my-view').should == 3
224
+ end
225
+
226
+ it "should add multiple points for multiple matching parents" do
227
+ score_for(@view, '.v1 .v2 .v3 .v4 #my-view').should == 5
228
+ end
229
+
230
+ it "should match parents at any level" do
231
+ score_for(@view, '.v3 #my-view').should == 2
232
+ score_for(@view, '.v2 #my-view').should == 2
233
+ score_for(@view, '.v1 .v3 #my-view').should == 3
234
+ end
235
+
236
+ it "should return 0 if no matching parent found" do
237
+ score_for(@view, '.non-existing #my-view').should == 0
238
+ end
239
+ end
240
+
241
+ describe "multiple different matchers" do
242
+ before do
243
+ @view.id = 'my-view'
244
+ @view.className = 'classy'
245
+ end
246
+
247
+ it "gets score out of multiple matchers if one of them is matching" do
248
+ score_for(@view, "view, input, form").should == 1
249
+ end
250
+
251
+ it "return 0 if none of the matchers are matching" do
252
+ score_for(@view, "input,select").should == 0
253
+ end
254
+
255
+ it "gets the max score if there are multiple matches" do
256
+ score_for(@view, "view,.classy,view#my-view").should == 2
257
+ end
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,83 @@
1
+ describe UnderOs::Page::Stylesheet do
2
+ before do
3
+ @stylesheet = UnderOs::Page::Stylesheet.new
4
+ end
5
+
6
+ describe '#initialize' do
7
+ it "should make an empty stylesheet" do
8
+ @stylesheet.rules.should == {}
9
+ end
10
+
11
+ it "should allow initialize with some rules" do
12
+ stylesheet = UnderOs::Page::Stylesheet.new(button: {color: 'orange'})
13
+ stylesheet.rules.should == {'button' => {color: 'orange'}}
14
+ end
15
+ end
16
+
17
+ describe '#[]' do
18
+ it "should allow to set new style rules" do
19
+ @stylesheet['button'] = {color: :red}
20
+ @stylesheet['button'].should == {color: :red}
21
+ end
22
+
23
+ it "should allow to extend the rules" do
24
+ @stylesheet['button'] = {color: 'red'}
25
+ @stylesheet['button'] = {right: 50 }
26
+ @stylesheet['button'].should == {color: 'red', right: 50}
27
+ end
28
+
29
+ it "should overwrite existing rules when match" do
30
+ @stylesheet['button'] = {color: 'red', left: 20}
31
+ @stylesheet['button'] = {color: 'blue'}
32
+ @stylesheet['button'].should == {color: 'blue', left: 20}
33
+ end
34
+ end
35
+
36
+ describe '#<<' do
37
+ it "should merge another stylesheet into the current one" do
38
+ other_sytles = UnderOs::Page::Stylesheet.new(button: { color: 'blue' })
39
+ @stylesheet['button'] = {left: 30}
40
+ @stylesheet << other_sytles
41
+ @stylesheet['button'].should == {color: 'blue', left: 30}
42
+ end
43
+ end
44
+
45
+ describe '#+' do
46
+ it "should create a new stylesheet combined out of the two" do
47
+ sheet1 = UnderOs::Page::Stylesheet.new(button: { color: 'blue' })
48
+ sheet2 = UnderOs::Page::Stylesheet.new(button: { left: 20 })
49
+
50
+ sheet3 = sheet1 + sheet2
51
+
52
+ sheet1['button'].should == {color: 'blue'}
53
+ sheet2['button'].should == {left: 20}
54
+ sheet3['button'].should == {color: 'blue', left: 20}
55
+ end
56
+ end
57
+
58
+ describe '#load' do
59
+ it "should load rules from the given test stylesheet file" do
60
+ @stylesheet.load('test.css')
61
+ @stylesheet.rules.should == {
62
+ "page"=>{:backgroundColor=>"yellow"},
63
+ ".test"=>{:backgroundColor=>"green"}
64
+ }
65
+ end
66
+ end
67
+
68
+ describe '#styles_for' do
69
+ before do
70
+ @view = UnderOs::UI::View.new(class: 'test')
71
+ @stylesheet.load('app.css')
72
+ @stylesheet.load('test.css')
73
+ end
74
+
75
+ it "should calculate the styles correctly" do
76
+ @stylesheet.styles_for(@view).should == {
77
+ color: 'yellow',
78
+ backgroundColor: 'green',
79
+ borderRadius: 10
80
+ }
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,5 @@
1
+ describe UnderOs::Page do
2
+ before do
3
+ @page = TestPage.new
4
+ end
5
+ end
@@ -0,0 +1,77 @@
1
+ describe UnderOs::Parser::CSS do
2
+ before do
3
+ @parser = UnderOs::Parser::CSS.new
4
+ end
5
+
6
+ it "should parse simple tags" do
7
+ @parser.parse(%Q[
8
+ page {
9
+ background-color: darkgray;
10
+ }
11
+ ]).should == {'page' => {backgroundColor: "darkgray"}}
12
+ end
13
+
14
+ it "should unquote quoted values" do
15
+ @parser.parse(%Q{
16
+ page {
17
+ background-image: "image.png";
18
+ }
19
+ }).should == {'page' => {backgroundImage: "image.png"}}
20
+ end
21
+
22
+ it "should parse heaps of styles" do
23
+ @parser.parse(%Q{
24
+ button {
25
+ width: 79px;
26
+ height: 79px;
27
+ color: black;
28
+ background: white;
29
+ border-radius: 0px;
30
+ }
31
+ }).should == {'button' => {
32
+ width: 79.0, height: 79.0, color: "black", backgroundColor: "white", borderRadius: 0.0
33
+ }}
34
+ end
35
+
36
+ it "should parse classes" do
37
+ @parser.parse(%Q[
38
+ .row1 { bottom: 0px; }
39
+ .row2 { bottom: 80px; }
40
+
41
+ .col1.col2 { left: 0; }
42
+ ]).should == {
43
+ '.row1' => {bottom: 0.0},
44
+ '.row2' => {bottom: 80.0},
45
+ '.col1.col2' => {left: 0.0}
46
+ }
47
+ end
48
+
49
+ it "should parse tags and styles" do
50
+ @parser.parse(%Q[
51
+ button.double { width: 159; }
52
+ button.ops { background: yellow }
53
+ ]).should == {
54
+ 'button.double' => {width: 159.0},
55
+ 'button.ops' => {backgroundColor: "yellow"}
56
+ }
57
+ end
58
+
59
+ it "should parse complex rules" do
60
+ @parser.parse(%Q{
61
+ icon#delete .col1.col2 { color: red }
62
+ }).should == {
63
+ 'icon#delete .col1.col2' => {color: "red"}
64
+ }
65
+ end
66
+
67
+ it "should parse several rules" do
68
+ @parser.parse(%Q{
69
+ input, textarea {
70
+ width: 100;
71
+ }
72
+ }).should == {
73
+ 'input' => {width: 100.0},
74
+ 'textarea' => {width: 100.0}
75
+ }
76
+ end
77
+ end
@@ -0,0 +1,152 @@
1
+ describe UnderOs::Parser::HTML do
2
+
3
+ def parse(src)
4
+ @parser ||= UnderOs::Parser::HTML.new
5
+ @parser.parse(src)
6
+ end
7
+
8
+ it "should parse simple tags" do
9
+ parse(%Q{
10
+ <page>
11
+ asdf
12
+ </page>
13
+ }).should == [{
14
+ tag: 'page',
15
+ text: 'asdf',
16
+ attrs: {}
17
+ }]
18
+ end
19
+
20
+ it "should parse tag attributes" do
21
+ parse(%Q{
22
+ <page title="My Page" id='my-page'>
23
+ </page>
24
+ }).should == [{
25
+ tag: 'page',
26
+ attrs: {
27
+ title: "My Page",
28
+ id: "my-page"
29
+ }
30
+ }]
31
+ end
32
+
33
+ it "should parse tad data-attributes" do
34
+ parse(%Q{
35
+ <view data-one="1" data-two="2" data-three="true" data-four-and-half="four/2"></view>
36
+ }).should == [{
37
+ tag: 'view',
38
+ attrs: {
39
+ data: {
40
+ one: '1',
41
+ two: '2',
42
+ three: true,
43
+ fourAndHalf: 'four/2'
44
+ }
45
+ }
46
+ }]
47
+ end
48
+
49
+ it "should process nested views" do
50
+ parse(%Q{
51
+ <page>
52
+ <view id="my-view">
53
+ <view class="my-view">
54
+ </view>
55
+ </view>
56
+ </page>
57
+ }).should == [{
58
+ tag: "page", attrs: {}, children: [
59
+ {tag: "view", attrs: {id: "my-view"}, children: [
60
+ {tag: "view", attrs: {class: "my-view"}}
61
+ ]}
62
+ ]
63
+ }]
64
+ end
65
+
66
+ it "should handle terminal nodes correctly" do
67
+ parse(%Q{
68
+ <page>
69
+ <img src="my-image.jpg" />
70
+ <button>Boo Hoo</button>
71
+ </page>
72
+ }).should == [{
73
+ tag: "page", attrs: {}, children: [
74
+ {tag: "img", attrs: {src: "my-image.jpg"}},
75
+ {tag: "button", attrs: {}, text: "Boo Hoo"}
76
+ ]
77
+ }]
78
+ end
79
+
80
+ it "should handle same tags correctly" do
81
+ parse(%Q{
82
+ <view id="level1">
83
+ <view id='level2'>
84
+ <button>A</button>
85
+ <button>B</button>
86
+
87
+ <view id="level3">
88
+ <img src="test.png" />
89
+ </view>
90
+
91
+ <view id="level4">
92
+ <icon type="ok">
93
+ <label>A</label>
94
+ <label>B</label>
95
+ </view>
96
+ </view>
97
+ </view>
98
+ }).should == [{
99
+ tag: "view", attrs: {id: "level1"}, children: [
100
+ {tag: "view", attrs: {id: "level2"}, children: [
101
+ {tag: "button", attrs: {}, text: "A"},
102
+ {tag: "button", attrs: {}, text: "B"},
103
+
104
+ {tag: "view", attrs: {id: "level3"}, children: [
105
+ {tag: "img", attrs: {src: "test.png"}}
106
+ ]},
107
+
108
+ {tag: "view", attrs: {id: "level4"}, children: [
109
+ {tag: "icon", attrs: {type: "ok"}},
110
+ {tag: "label", attrs: {}, text: "A"},
111
+ {tag: "label", attrs: {}, text: "B"}
112
+ ]}
113
+ ]}
114
+ ]}
115
+ ]
116
+ end
117
+
118
+ it "should handle multiple single tags correctly" do
119
+ parse(%Q{
120
+ <view>
121
+ <img>
122
+ <icon>
123
+ <slide>
124
+ </view>
125
+ <switch>
126
+ <progress>
127
+ }).should == [
128
+ {tag: "view", attrs: {}, children: [
129
+ {tag: "img", attrs: {}},
130
+ {tag: "icon", attrs: {}},
131
+ {tag: "slide", attrs: {}}
132
+ ]},
133
+ {tag: "switch", attrs: {}},
134
+ {tag: "progress", attrs: {}}
135
+ ]
136
+ end
137
+
138
+ it "should skipp all the comments" do
139
+ parse(%Q{
140
+ <view>
141
+ <!-- <img> -->
142
+ <icon>
143
+ <!-- <slide> -->
144
+ </view>
145
+ }).should == [
146
+ {tag: "view", attrs: {}, children: [
147
+ {tag: "icon", attrs: {}}
148
+ ]}
149
+ ]
150
+ end
151
+
152
+ end