under-os-ui 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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