dryml 1.3.3 → 1.4.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/Gemfile +6 -0
  2. data/README +2 -0
  3. data/Rakefile +2 -1
  4. data/VERSION +1 -1
  5. data/cucumber.yml +9 -0
  6. data/dryml.gemspec +4 -2
  7. data/features/cookbook/01_simple_page_templates.feature +44 -0
  8. data/features/cookbook/02_defining_simple_tags.feature +375 -0
  9. data/features/cookbook/03_implicit_context.feature +229 -0
  10. data/features/cookbook/04_tag_attributes.feature +120 -0
  11. data/features/cookbook/05_repeated_and_optional_content.feature +241 -0
  12. data/features/cookbook/06_pseudo_parameters.feature +191 -0
  13. data/features/cookbook/07_nested_parameters.feature +147 -0
  14. data/features/cookbook/08_customizing_tags.feature +307 -0
  15. data/features/cookbook/09_aliasing_tags.feature +50 -0
  16. data/features/cookbook/10_polymorphic_tags.feature +168 -0
  17. data/features/cookbook/11_wrapping_content.feature +57 -0
  18. data/features/cookbook/12_local_and_scoped_variables.feature +102 -0
  19. data/features/doctest_examples.feature +187 -0
  20. data/features/merge_params.feature +36 -0
  21. data/features/replace_parameters.feature +21 -0
  22. data/features/static_tags.feature +91 -0
  23. data/features/step_definitions/contexts.rb +25 -0
  24. data/features/step_definitions/dom_comparison.rb +10 -0
  25. data/features/step_definitions/rendering.rb +21 -0
  26. data/features/support/env.rb +32 -0
  27. data/features/support/models/author.rb +18 -0
  28. data/features/support/models/blog_post.rb +37 -0
  29. data/features/support/models/discussion.rb +15 -0
  30. data/features/support/models/post.rb +12 -0
  31. data/features/support/strip_formatter.rb +14 -0
  32. data/lib/dryml/dryml_builder.rb +4 -14
  33. data/lib/dryml/dryml_doc.rb +6 -1
  34. data/lib/dryml/helper.rb +17 -1
  35. data/lib/dryml/part_context.rb +12 -15
  36. data/lib/dryml/railtie/template_handler.rb +1 -3
  37. data/lib/dryml/railtie.rb +1 -0
  38. data/lib/dryml/taglib.rb +24 -30
  39. data/lib/dryml/template.rb +32 -86
  40. data/lib/dryml/template_environment.rb +40 -17
  41. data/lib/dryml.rb +22 -11
  42. data/taglibs/core.dryml +18 -12
  43. data/taglibs/dryml.dryml +3 -0
  44. metadata +97 -56
@@ -0,0 +1,229 @@
1
+ Feature: The implicit context
2
+ Background:
3
+ Given a file named "example_taglib.dryml" with:
4
+ """
5
+ <def tag="view"><%= h this.to_s %></def>
6
+
7
+ <def tag="l"><a href="#{this.url}" param="default"/></def>
8
+
9
+ <def tag="page">
10
+ <html>
11
+ <head>
12
+ <title>My Blog</title>
13
+ </head>
14
+ <body param="content"/>
15
+ </html>
16
+ </def>
17
+ """
18
+
19
+ Scenario: Rendering a blog post
20
+ Given a file named "show.dryml" with:
21
+ """
22
+ <page>
23
+ <content:>
24
+ <h2><view:title/></h2>
25
+ <div class="details">
26
+ Published by <l:author><view:name/></l> on <view:published-at/>.
27
+ </div>
28
+ <div class="post-body">
29
+ <view:body/>
30
+ </div>
31
+ </content:>
32
+ </page>
33
+ """
34
+ When I include the taglib "example_taglib"
35
+ And the current context is a blog post
36
+ And I render "show.dryml"
37
+ Then the output DOM should be:
38
+ """
39
+ <html>
40
+ <head>
41
+ <title>My Blog</title>
42
+ </head>
43
+ <body class="content">
44
+ <h2>A Blog Post</h2>
45
+ <div class="details">
46
+ Published by <a href="/authors/1">Nobody</a> on 2011-12-30 10:25:00 UTC.
47
+ </div>
48
+ <div class="post-body">
49
+ Some body content
50
+ </div>
51
+ </body>
52
+ </html>
53
+ """
54
+
55
+ Scenario: Rendering a blog post using only with
56
+ Given a file named "show.dryml" with:
57
+ """
58
+ <page>
59
+ <content:>
60
+ <h2><view with="&this.title"/></h2>
61
+ <div class="details">
62
+ Published by <l with="&this.author"><view with="&this.name"/></l>
63
+ on <view with="&this.published_at"/>.
64
+ </div>
65
+ <div class="post-body">
66
+ <view with="&this.body"/>
67
+ </div>
68
+ </content:>
69
+ </page>
70
+ """
71
+ When I include the taglib "example_taglib"
72
+ And the current context is a blog post
73
+ And I render "show.dryml"
74
+ Then the output DOM should be:
75
+ """
76
+ <html>
77
+ <head>
78
+ <title>My Blog</title>
79
+ </head>
80
+ <body class="content">
81
+ <h2>A Blog Post</h2>
82
+ <div class="details">
83
+ Published by <a href="/authors/1">Nobody</a> on 2011-12-30 10:25:00 UTC.
84
+ </div>
85
+ <div class="post-body">
86
+ Some body content
87
+ </div>
88
+ </body>
89
+ </html>
90
+ """
91
+
92
+ Scenario: Rendering a blog post using only field
93
+ Given a file named "show.dryml" with:
94
+ """
95
+ <page>
96
+ <content:>
97
+ <h2><view field="title"/></h2>
98
+ <div class="details">
99
+ Published by <l field="author"><view field="name"/></l>
100
+ on <view field="published_at"/>.
101
+ </div>
102
+ <div class="post-body">
103
+ <view field="body"/>
104
+ </div>
105
+ </content:>
106
+ </page>
107
+ """
108
+ When I include the taglib "example_taglib"
109
+ And the current context is a blog post
110
+ And I render "show.dryml"
111
+ Then the output DOM should be:
112
+ """
113
+ <html>
114
+ <head>
115
+ <title>My Blog</title>
116
+ </head>
117
+ <body class="content">
118
+ <h2>A Blog Post</h2>
119
+ <div class="details">
120
+ Published by <a href="/authors/1">Nobody</a> on 2011-12-30 10:25:00 UTC.
121
+ </div>
122
+ <div class="post-body">
123
+ Some body content
124
+ </div>
125
+ </body>
126
+ </html>
127
+ """
128
+
129
+ Scenario: field chains
130
+ Given a file named "show.dryml" with:
131
+ """
132
+ <div><do:author.name><view /></do></div>
133
+ <div><do field="author.name"><view /></do></div>
134
+ """
135
+ When I include the taglib "example_taglib"
136
+ And the current context is a blog post
137
+ And I render "show.dryml"
138
+ Then the output DOM should be:
139
+ """
140
+ <div>Nobody</div>
141
+ <div>Nobody</div>
142
+ """
143
+
144
+ Scenario: this_field and this_parent
145
+ Given a file named "show.dryml" with:
146
+ """
147
+ <div>
148
+ <do with="&this.author.name">
149
+ <div><view /></div>
150
+ <div><%= this_parent.class.name %></div>
151
+ <div><%= this_field %></div>
152
+ </do>
153
+ </div>
154
+ <div>
155
+ <do with="&this.author" field="name">
156
+ <div><view /></div>
157
+ <div><%= this_parent.class.name %></div>
158
+ <div><%= this_field %></div>
159
+ </do>
160
+ </div>
161
+ """
162
+ When I include the taglib "example_taglib"
163
+ And the current context is a blog post
164
+ And I render "show.dryml"
165
+ Then the output DOM should be:
166
+ """
167
+ <div>
168
+ <div>Nobody</div>
169
+ <div>NilClass</div>
170
+ <div></div>
171
+ </div>
172
+ <div>
173
+ <div>Nobody</div>
174
+ <div>Author</div>
175
+ <div>name</div>
176
+ </div>
177
+ """
178
+
179
+ Scenario: indexing into a collection
180
+ Given a file named "show.dryml" with:
181
+ """
182
+ <div><do field="1"><view /></do></div>
183
+ <div><do field="3"><view /></do></div>
184
+ """
185
+ When I include the taglib "example_taglib"
186
+ And the current context is an array
187
+ And I render "show.dryml"
188
+ Then the output DOM should be:
189
+ """
190
+ <div>bar</div>
191
+ <div>blam</div>
192
+ """
193
+
194
+ Scenario: repeating on a collection stores the index in this_field
195
+ Given a file named "show.dryml" with:
196
+ """
197
+ <repeat>
198
+ <div>
199
+ <span><%= this_field %></span>
200
+ <span><view /></span>
201
+ </div>
202
+ </repeat>
203
+ """
204
+ When I include the taglib "example_taglib"
205
+ And the current context is an array
206
+ And I render "show.dryml"
207
+ Then the output DOM should be:
208
+ """
209
+ <div>
210
+ <span>0</span>
211
+ <span>foo</span>
212
+ </div>
213
+ <div>
214
+ <span>1</span>
215
+ <span>bar</span>
216
+ </div>
217
+ <div>
218
+ <span>2</span>
219
+ <span>baz</span>
220
+ </div>
221
+ <div>
222
+ <span>3</span>
223
+ <span>blam</span>
224
+ </div>
225
+ <div>
226
+ <span>4</span>
227
+ <span>mumble</span>
228
+ </div>
229
+ """
@@ -0,0 +1,120 @@
1
+ Feature: Tag attributes
2
+
3
+ Scenario: A tag with one attribute
4
+ Given a file named "example_taglib.dryml" with:
5
+ """
6
+ <def tag="help-link" attrs="file">
7
+ <a class="help" href="/help/#{file}.html" param="default"/>
8
+ </def>
9
+ """
10
+ And a file named "example.dryml" with:
11
+ """
12
+ <help-link file="intro">Introductory Help</help-link>
13
+ """
14
+ When I include the taglib "example_taglib"
15
+ And I render "example.dryml"
16
+ Then the output DOM should be:
17
+ """
18
+ <a class="help" href="/help/intro.html">Introductory Help</a>
19
+ """
20
+
21
+ Scenario: A tag with a boolean attribute
22
+ Given a file named "example_taglib.dryml" with:
23
+ """
24
+ <def tag="help-link" attrs="file, new-window">
25
+ <a class="help" href="/help/#{file}.html" target="#{new_window ? '_blank' : '_self' }" param="default"/>
26
+ </def>
27
+ """
28
+ And a file named "example.dryml" with:
29
+ """
30
+ <help-link file="intro" new-window="&true">Introductory Help In A New Window</help-link>
31
+ <help-link file="intro" new-window="&false">Introductory Help</help-link>
32
+ """
33
+ When I include the taglib "example_taglib"
34
+ And I render "example.dryml"
35
+ Then the output DOM should be:
36
+ """
37
+ <a class="help" href="/help/intro.html" target="_blank">Introductory Help In A New Window</a>
38
+ <a class="help" href="/help/intro.html" target="_self">Introductory Help</a>
39
+ """
40
+
41
+ Scenario: A tag with a flag attribute
42
+ Given a file named "example_taglib.dryml" with:
43
+ """
44
+ <def tag="help-link" attrs="file, new-window">
45
+ <a class="help" href="/help/#{file}.html" target="#{new_window ? '_blank' : '_self' }" param="default"/>
46
+ </def>
47
+ """
48
+ And a file named "example.dryml" with:
49
+ """
50
+ <help-link file="intro" new-window>Introductory Help In A New Window</help-link>
51
+ <help-link file="intro">Introductory Help</help-link>
52
+ """
53
+ When I include the taglib "example_taglib"
54
+ And I render "example.dryml"
55
+ Then the output DOM should be:
56
+ """
57
+ <a class="help" href="/help/intro.html" target="_blank">Introductory Help In A New Window</a>
58
+ <a class="help" href="/help/intro.html" target="_self">Introductory Help</a>
59
+ """
60
+
61
+ Scenario: Using merge-attrs
62
+ Given a file named "example_taglib.dryml" with:
63
+ """
64
+ <def tag="markdown-help">
65
+ <a href="http://daringfireball.net/..." merge-attrs param="default"/>
66
+ </def>
67
+ """
68
+ And a file named "example.dryml" with:
69
+ """
70
+ Add formatting using <markdown-help target="_blank">markdown</markdown-help>
71
+ """
72
+ When I include the taglib "example_taglib"
73
+ And I render "example.dryml"
74
+ Then the output DOM should be:
75
+ """
76
+ Add formatting using <a href="http://daringfireball.net/..." target="_blank">markdown</a>
77
+ """
78
+
79
+ Scenario: Using merge-attrs and attributes_for
80
+ Given a file named "example_taglib.dryml" with:
81
+ """
82
+ <def tag="help-link" attrs="file, new-window">
83
+ <a class="help" href="/help/#{file}.html" target="#{new_window ? '_blank' : '_self' }" param="default"/>
84
+ </def>
85
+
86
+ <def tag="decorated-help" attrs="image, alt">
87
+ <help-link merge-attrs="&attributes - attrs_for(:help_link)">
88
+ <img src="/images/#{image}.png" alt="#{alt || image}" /><do param="default"/>
89
+ </help-link>
90
+ </def>
91
+ """
92
+ And a file named "example.dryml" with:
93
+ """
94
+ <decorated-help image="intro" file="intro" new-window>Introductory Help In A New Window</decorated-help>
95
+ """
96
+ When I include the taglib "example_taglib"
97
+ And I render "example.dryml"
98
+ Then the output DOM should be:
99
+ """
100
+ <a class="help" href="/help/.html" target="_self"><img alt="intro" src="/images/intro.png"/>Introductory Help In A New Window</a>
101
+ """
102
+
103
+ Scenario: Merging the class attribute
104
+ Given a file named "example_taglib.dryml" with:
105
+ """
106
+ <def tag="help-link" attrs="file">
107
+ <a class="help" href="/help/#{file}.html" param="default" merge-attrs/>
108
+ </def>
109
+ """
110
+ And a file named "example.dryml" with:
111
+ """
112
+ <help-link file="intro" class="important">Introductory Help</help-link>
113
+ """
114
+ When I include the taglib "example_taglib"
115
+ And I render "example.dryml"
116
+ Then the output DOM should be:
117
+ """
118
+ <a class="help important" href="/help/intro.html">Introductory Help</a>
119
+ """
120
+
@@ -0,0 +1,241 @@
1
+ Feature: Repeated and optional content
2
+
3
+ Scenario: The if tag
4
+ Given a file named "example.dryml" with:
5
+ """
6
+ <% some_var = 'foo' %>
7
+ <if test="&some_var"><p>some_var is true</p></if>
8
+ <% some_other_var = '' %>
9
+ <if test="&some_other_var"><p>some_other_var is true</p></if>
10
+ """
11
+ When I render "example.dryml"
12
+ Then the output DOM should be:
13
+ """
14
+ <p>some_var is true</p>
15
+ """
16
+
17
+ Scenario: The else tag
18
+ Given a file named "example.dryml" with:
19
+ """
20
+ <% some_var = 'foo' %>
21
+ <if test="&some_var"><p>some_var is true</p></if>
22
+ <else><p>some_var is false</p></else>
23
+ <% some_other_var = '' %>
24
+ <if test="&some_other_var"><p>some_other_var is true</p></if>
25
+ <else><p>some_other_var is false</p></else>
26
+ """
27
+ When I render "example.dryml"
28
+ Then the output DOM should be:
29
+ """
30
+ <p>some_var is true</p>
31
+ <p>some_other_var is false</p>
32
+ """
33
+
34
+ Scenario: The unless tag
35
+ Given a file named "example.dryml" with:
36
+ """
37
+ <% some_var = 'foo' %>
38
+ <unless test="&some_var"><p>some_var is false</p></unless>
39
+ <% some_other_var = '' %>
40
+ <unless test="&some_other_var"><p>some_other_var is false</p></unless>
41
+ """
42
+ When I render "example.dryml"
43
+ Then the output DOM should be:
44
+ """
45
+ <p>some_other_var is false</p>
46
+ """
47
+
48
+ Scenario: The if tag with a field
49
+ Given a file named "example.dryml" with:
50
+ """
51
+ <if:author.name><p>author name is not blank</p></if>
52
+ <% this.author.name = '' %>
53
+ <if:author.name><p>author name is still not blank</p></if>
54
+ <else><p>now it is</p></else>
55
+ """
56
+ When the current context is a blog post
57
+ And I render "example.dryml"
58
+ Then the output DOM should be:
59
+ """
60
+ <p>author name is not blank</p>
61
+ <p>now it is</p>
62
+ """
63
+
64
+ Scenario: The if parameter
65
+ Given a file named "example.dryml" with:
66
+ """
67
+ <% some_var = 'foo' %>
68
+ <p if="&some_var">some_var is true</p>
69
+ <% some_other_var = '' %>
70
+ <p if="&some_other_var">some_other_var is true</p>
71
+ """
72
+ When I render "example.dryml"
73
+ Then the output DOM should be:
74
+ """
75
+ <p>some_var is true</p>
76
+ """
77
+
78
+ Scenario: The unless parameter
79
+ Given a file named "example.dryml" with:
80
+ """
81
+ <% some_var = 'foo' %>
82
+ <p unless="&some_var">some_var is false</p>
83
+ <% some_other_var = '' %>
84
+ <p unless="&some_other_var">some_other_var is false</p>
85
+ """
86
+ When I render "example.dryml"
87
+ Then the output DOM should be:
88
+ """
89
+ <p>some_other_var is false</p>
90
+ """
91
+
92
+ Scenario: The if parameter with a field - NOTE NO &
93
+ Given a file named "example.dryml" with:
94
+ """
95
+ <p if="author.name">author name is not blank</p>
96
+ <% this.author.name = '' %>
97
+ <p if="author.name">author name is still not blank</p>
98
+ <else><p>now it is</p></else>
99
+ """
100
+ When the current context is a blog post
101
+ And I render "example.dryml"
102
+ Then the output DOM should be:
103
+ """
104
+ <p>author name is not blank</p>
105
+ <p>now it is</p>
106
+ """
107
+
108
+ Scenario: The if parameter without an argument
109
+ Given a file named "example.dryml" with:
110
+ """
111
+ <do:author.name><p if>author name is not blank</p></do>
112
+ <% this.author.name = '' %>
113
+ <do:author.name><p if>author name is still not blank</p></do>
114
+ <else><p>now it is</p></else>
115
+ """
116
+ When the current context is a blog post
117
+ And I render "example.dryml"
118
+ Then the output DOM should be:
119
+ """
120
+ <p>author name is not blank</p>
121
+ <p>now it is</p>
122
+ """
123
+
124
+ Scenario: The if parameter without an argument applies to the surrounding context
125
+ Given a file named "example.dryml" with:
126
+ """
127
+ <% this.author = '' %>
128
+ <do:author if><p>first if is true</p></do>
129
+ <do:author><do if><p>second if is true</p></do></do>
130
+ """
131
+ When the current context is a blog post
132
+ And I render "example.dryml"
133
+ Then the output DOM should be:
134
+ """
135
+ <p>first if is true</p>
136
+ """
137
+
138
+ Scenario: repeat tag
139
+ Given a file named "example.dryml" with:
140
+ """
141
+ <repeat with="&[1,2,3,4]">
142
+ <p><%= this %></p>
143
+ </repeat>
144
+ """
145
+ When I render "example.dryml"
146
+ Then the output DOM should be:
147
+ """
148
+ <p>1</p>
149
+ <p>2</p>
150
+ <p>3</p>
151
+ <p>4</p>
152
+ """
153
+
154
+ Scenario: repeat attribute
155
+ Given a file named "example.dryml" with:
156
+ """
157
+ <p repeat="&[1,2,3,4]"><%= this %></p>
158
+ """
159
+ When I render "example.dryml"
160
+ Then the output DOM should be:
161
+ """
162
+ <p>1</p>
163
+ <p>2</p>
164
+ <p>3</p>
165
+ <p>4</p>
166
+ """
167
+
168
+ Scenario: attributes on a repeated tag are re-evaluated at each iteration
169
+ Given a file named "example.dryml" with:
170
+ """
171
+ <p repeat="&[1,2,3,4]" id="#{this}"><%= this %></p>
172
+ """
173
+ When I render "example.dryml"
174
+ Then the output DOM should be:
175
+ """
176
+ <p id="1">1</p>
177
+ <p id="2">2</p>
178
+ <p id="3">3</p>
179
+ <p id="4">4</p>
180
+ """
181
+
182
+ Scenario: even-odd scoped variable
183
+ Given a file named "example.dryml" with:
184
+ """
185
+ <p repeat="&[1,2,3,4]" class="#{scope.even_odd}"><%= this %></p>
186
+ """
187
+ When I render "example.dryml"
188
+ Then the output DOM should be:
189
+ """
190
+ <p class="odd">1</p>
191
+ <p class="even">2</p>
192
+ <p class="odd">3</p>
193
+ <p class="even">4</p>
194
+ """
195
+
196
+ Scenario: repeating the implicit context with if
197
+ Given a file named "example.dryml" with:
198
+ """
199
+ <do with="&[1,2,nil,4]">
200
+ <repeat if><p id="#{this}"><%= this %></p></repeat>
201
+ </do>
202
+ <do with="&[]">
203
+ <repeat if><p id="#{this}"><%= this %></p></repeat>
204
+ </do>
205
+ """
206
+ When I render "example.dryml"
207
+ Then the output DOM should be:
208
+ """
209
+ <p id="1">1</p>
210
+ <p id="2">2</p>
211
+ <p id=""></p>
212
+ <p id="4">4</p>
213
+ """
214
+
215
+ Scenario: first_item? helper
216
+ Given a file named "example.dryml" with:
217
+ """
218
+ <p repeat="&[1,2,3,4]" id="#{this}"><%= first_item? ? this*10 : this %></p>
219
+ """
220
+ When I render "example.dryml"
221
+ Then the output DOM should be:
222
+ """
223
+ <p id="1">10</p>
224
+ <p id="2">2</p>
225
+ <p id="3">3</p>
226
+ <p id="4">4</p>
227
+ """
228
+
229
+ Scenario: repeating over a hash sets this_key (not reliable on Ruby < 1.9)
230
+ Given a file named "example.dryml" with:
231
+ """
232
+ <p repeat="&{:foo => 1, :bar => 2, :baz => 3}" id="#{this_key}"><%= this %></p>
233
+ """
234
+ When I render "example.dryml"
235
+ Then the output DOM should be:
236
+ """
237
+ <p id="foo">1</p>
238
+ <p id="bar">2</p>
239
+ <p id="baz">3</p>
240
+ """
241
+