undies 1.2.0 → 2.0.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.
- data/.gitignore +2 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +10 -5
- data/Rakefile +2 -4
- data/bench/large.html.rb +32 -0
- data/bench/procs.rb +106 -0
- data/bench/profiler.rb +25 -0
- data/bench/small.html.rb +32 -0
- data/bench/verylarge.html.rb +32 -0
- data/lib/undies/element.rb +61 -61
- data/lib/undies/named_source.rb +54 -0
- data/lib/undies/node.rb +16 -24
- data/lib/undies/node_buffer.rb +35 -0
- data/lib/undies/output.rb +64 -0
- data/lib/undies/source.rb +58 -12
- data/lib/undies/source_stack.rb +22 -0
- data/lib/undies/template.rb +47 -134
- data/lib/undies/version.rb +1 -1
- data/lib/undies.rb +1 -11
- data/test/element_test.rb +106 -99
- data/test/helper.rb +4 -2
- data/test/irb.rb +3 -4
- data/test/named_source_test.rb +91 -0
- data/test/node_buffer_test.rb +54 -0
- data/test/node_test.rb +19 -10
- data/test/output_test.rb +116 -0
- data/test/source_stack_test.rb +48 -0
- data/test/source_test.rb +131 -27
- data/test/template_test.rb +120 -145
- data/test/templates/layout.html.rb +1 -1
- data/undies.gemspec +1 -1
- metadata +27 -23
- data/lib/undies/element_stack.rb +0 -35
- data/lib/undies/node_list.rb +0 -35
- data/lib/undies/partial.rb +0 -23
- data/lib/undies/partial_data.rb +0 -32
- data/test/element_stack_test.rb +0 -77
- data/test/fixtures/partial_template.rb +0 -6
- data/test/node_list_test.rb +0 -69
- data/test/partial_data_test.rb +0 -100
- data/test/partial_test.rb +0 -63
data/lib/undies/source.rb
CHANGED
@@ -1,26 +1,72 @@
|
|
1
|
+
require 'undies/named_source'
|
2
|
+
|
1
3
|
module Undies
|
2
4
|
class Source
|
3
5
|
|
4
|
-
attr_reader :source, :data
|
6
|
+
attr_reader :source, :data, :layout
|
7
|
+
|
8
|
+
def initialize(*args, &block)
|
9
|
+
named = args.first.kind_of?(NamedSource) ? args.first : nil
|
10
|
+
args << block if block
|
11
|
+
self.args = named ? named.args.compact : args
|
12
|
+
end
|
5
13
|
|
6
|
-
def
|
7
|
-
|
14
|
+
def file?
|
15
|
+
!@source.kind_of?(::Proc)
|
16
|
+
end
|
8
17
|
|
9
|
-
|
10
|
-
if
|
11
|
-
|
18
|
+
def layouts
|
19
|
+
if layout
|
20
|
+
[self.layout, self.layout.layouts].flatten.compact
|
21
|
+
else
|
22
|
+
[]
|
12
23
|
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def layout_sources
|
27
|
+
self.layouts.collect{|l| l.source}
|
28
|
+
end
|
13
29
|
|
14
|
-
|
15
|
-
|
16
|
-
|
30
|
+
def ==(other_source)
|
31
|
+
self.source == other_source.source &&
|
32
|
+
self.layout_sources == other_source.layout_sources
|
33
|
+
end
|
34
|
+
|
35
|
+
def args=(values)
|
36
|
+
proc, opts, file = [
|
37
|
+
values.last.kind_of?(::Proc) ? values.pop : nil,
|
38
|
+
values.last.kind_of?(::Hash) ? values.pop : {},
|
39
|
+
values.last.kind_of?(::String) ? values.pop : nil
|
40
|
+
]
|
41
|
+
|
42
|
+
self.source = file || proc
|
43
|
+
self.layout = opts[:layout]
|
44
|
+
end
|
45
|
+
|
46
|
+
def source=(value)
|
47
|
+
if value.nil?
|
48
|
+
raise ArgumentError, "source name, file, or block required"
|
49
|
+
end
|
50
|
+
@data = if value.kind_of?(::Proc)
|
51
|
+
value
|
17
52
|
else
|
18
|
-
|
53
|
+
raise ArgumentError, "no source file '#{value}'" if !File.exists?(value.to_s)
|
54
|
+
File.send(File.respond_to?(:binread) ? :binread : :read, value.to_s)
|
19
55
|
end
|
56
|
+
@source = value
|
20
57
|
end
|
21
58
|
|
22
|
-
def
|
23
|
-
|
59
|
+
def layout=(value)
|
60
|
+
@layout = case value
|
61
|
+
when Source, NilClass
|
62
|
+
value
|
63
|
+
when ::Proc
|
64
|
+
Source.new(&value)
|
65
|
+
when ::String, NamedSource
|
66
|
+
Source.new(value)
|
67
|
+
else
|
68
|
+
raise ArgumentError, "invalid layout"
|
69
|
+
end
|
24
70
|
end
|
25
71
|
|
26
72
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "undies/source"
|
2
|
+
|
3
|
+
module Undies
|
4
|
+
class SourceStack < ::Array
|
5
|
+
|
6
|
+
# a source stack is used to manage which sources and any deeply nested
|
7
|
+
# layouts they are in. initialize this object with a content source obj
|
8
|
+
# and get a stack where the the top source is the outer most layout and
|
9
|
+
# the bottom source is the source used to initialize the stack (the content
|
10
|
+
# source). naturally any sources in between are the intermediate layouts
|
11
|
+
# for the content source
|
12
|
+
|
13
|
+
def initialize(source)
|
14
|
+
super([source, source.layouts].flatten.compact)
|
15
|
+
end
|
16
|
+
|
17
|
+
def pop
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
data/lib/undies/template.rb
CHANGED
@@ -1,47 +1,69 @@
|
|
1
|
-
require 'undies/
|
2
|
-
require 'undies/
|
3
|
-
require 'undies/element'
|
1
|
+
require 'undies/source_stack'
|
2
|
+
require 'undies/output'
|
4
3
|
|
5
4
|
module Undies
|
6
5
|
class Template
|
7
6
|
|
8
|
-
#
|
7
|
+
# have as many methods to the class level as possilbe to keep from
|
8
|
+
# polluting the public instance methods, the instance scope, and to
|
9
|
+
# maximize the effectiveness of the Template#method_missing logic
|
9
10
|
|
10
|
-
|
11
|
+
def self.output(template)
|
12
|
+
template.instance_variable_get("@_undies_output")
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(source, data, output)
|
16
|
+
# setup the source stack and output objects
|
17
|
+
raise ArgumentError, "please provide a Source object" if !source.kind_of?(Source)
|
18
|
+
@_undies_source_stack = SourceStack.new(source)
|
19
|
+
raise ArgumentError, "please provide an Output object" if !output.kind_of?(Output)
|
20
|
+
@_undies_output = output
|
21
|
+
|
22
|
+
# apply data to template scope
|
23
|
+
raise ArgumentError if !data.kind_of?(::Hash)
|
24
|
+
if (data.keys.map(&:to_s) & self.public_methods.map(&:to_s)).size > 0
|
25
|
+
raise ArgumentError, "data conflicts with template public methods."
|
26
|
+
end
|
27
|
+
metaclass = class << self; self; end
|
28
|
+
data.each {|key, value| metaclass.class_eval { define_method(key){value} }}
|
11
29
|
|
12
|
-
|
13
|
-
self.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
self.___compile { self.___render(self.___markup) if self.___layout }
|
30
|
+
# yield to recursivley render the source stack
|
31
|
+
self.__yield
|
32
|
+
|
33
|
+
# flush any remaining output to the stream
|
34
|
+
@_undies_output.flush
|
18
35
|
end
|
19
36
|
|
20
|
-
|
21
|
-
|
37
|
+
# call this to render template source
|
38
|
+
# use this method in layouts to insert a layout's content source
|
39
|
+
def __yield
|
40
|
+
return if @_undies_source_stack.nil? || (source = @_undies_source_stack.pop).nil?
|
41
|
+
if source.file?
|
42
|
+
instance_eval(source.data, source.source, 1)
|
43
|
+
else
|
44
|
+
instance_eval(&source.data)
|
45
|
+
end
|
22
46
|
end
|
23
47
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
48
|
+
# call this to render partial source embedded in a template
|
49
|
+
# partial source is rendered with its own scope/data but shares
|
50
|
+
# its parent template's output object
|
51
|
+
def __partial(source, data)
|
52
|
+
Undies::Template.new(source, data, @_undies_output)
|
27
53
|
end
|
28
54
|
|
55
|
+
# Add a text node (data escaped) to the nodes of the current node
|
56
|
+
def _(data=""); self.__ self.escape_html(data.to_s); end
|
57
|
+
|
29
58
|
# Add a text node with the data un-escaped
|
30
|
-
def __(data="")
|
31
|
-
node = Node.new(data.to_s)
|
32
|
-
self.___io << node.to_s if self.___io
|
33
|
-
self.___add(node)
|
34
|
-
end
|
59
|
+
def __(data=""); @_undies_output.node(data.to_s); end
|
35
60
|
|
36
61
|
# Add an element to the nodes of the current node
|
37
|
-
def element(
|
38
|
-
self.___add(Element.new(self.___stack, name, attrs, &block))
|
39
|
-
end
|
62
|
+
def element(*args, &block); @_undies_output.element(*args, &block); end
|
40
63
|
alias_method :tag, :element
|
41
64
|
|
42
65
|
# Element proxy methods ('_<element>'') ========================
|
43
66
|
ELEM_METH_REGEX = /^_(.+)$/
|
44
|
-
|
45
67
|
def method_missing(meth, *args, &block)
|
46
68
|
if meth.to_s =~ ELEM_METH_REGEX
|
47
69
|
element($1, *args, &block)
|
@@ -49,7 +71,6 @@ module Undies
|
|
49
71
|
super
|
50
72
|
end
|
51
73
|
end
|
52
|
-
|
53
74
|
def respond_to?(*args)
|
54
75
|
if args.first.to_s =~ ELEM_METH_REGEX
|
55
76
|
true
|
@@ -70,119 +91,11 @@ module Undies
|
|
70
91
|
"/" => "/"
|
71
92
|
}
|
72
93
|
ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys)
|
73
|
-
|
74
94
|
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
75
95
|
def escape_html(string)
|
76
96
|
string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
|
77
97
|
end
|
78
98
|
# end Rip from Rack v1.3.0 =====================================
|
79
99
|
|
80
|
-
protected
|
81
|
-
|
82
|
-
# prefixing non-public methods with a triple underscore to not pollute
|
83
|
-
# metaclass locals scope
|
84
|
-
|
85
|
-
def ___compile
|
86
|
-
self.___render(self.___layout || self.___markup)
|
87
|
-
end
|
88
|
-
|
89
|
-
def ___render(source)
|
90
|
-
if source.file?
|
91
|
-
instance_eval(source.data, source.source, 1)
|
92
|
-
else
|
93
|
-
instance_eval(&source.data)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def ___locals=(data)
|
98
|
-
if !data.kind_of?(::Hash)
|
99
|
-
raise ArgumentError
|
100
|
-
end
|
101
|
-
if invalid_locals?(data.keys)
|
102
|
-
raise ArgumentError, "locals conflict with template's public methods."
|
103
|
-
end
|
104
|
-
data.each do |key, value|
|
105
|
-
self.___metaclass do
|
106
|
-
define_method(key) { value }
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def ___add(node)
|
112
|
-
self.___stack.last.___nodes.append(node)
|
113
|
-
end
|
114
|
-
|
115
|
-
def ___stack
|
116
|
-
@stack
|
117
|
-
end
|
118
|
-
|
119
|
-
def ___stack=(value)
|
120
|
-
raise ArgumentError if !value.respond_to?(:push) || !value.respond_to?(:pop)
|
121
|
-
@stack = value
|
122
|
-
end
|
123
|
-
|
124
|
-
def ___io
|
125
|
-
@io
|
126
|
-
end
|
127
|
-
|
128
|
-
def ___io=(value)
|
129
|
-
raise ArgumentError if value && !self.___is_a_stream?(value)
|
130
|
-
@io = value
|
131
|
-
end
|
132
|
-
|
133
|
-
def ___layout
|
134
|
-
@layout
|
135
|
-
end
|
136
|
-
|
137
|
-
def ___layout=(value)
|
138
|
-
if value && !(value.kind_of?(Source) && value.file?)
|
139
|
-
raise ArgumentError, "layout must be a file source"
|
140
|
-
end
|
141
|
-
@layout = value
|
142
|
-
end
|
143
|
-
|
144
|
-
def ___markup
|
145
|
-
@markup
|
146
|
-
end
|
147
|
-
|
148
|
-
def ___markup=(value)
|
149
|
-
raise ArgumentError if value && !value.kind_of?(Source)
|
150
|
-
@markup = value
|
151
|
-
end
|
152
|
-
|
153
|
-
def ___template_args(args, block)
|
154
|
-
[ args.last.kind_of?(::Hash) ? args.pop : {},
|
155
|
-
self.___is_a_stream?(args.last) ? args.pop : nil,
|
156
|
-
self.___layout_arg?(args, block) ? Source.new(args.pop) : nil,
|
157
|
-
Source.new(args.first || block)
|
158
|
-
]
|
159
|
-
end
|
160
|
-
|
161
|
-
def ___metaclass(&block)
|
162
|
-
metaclass = class << self; self; end
|
163
|
-
metaclass.class_eval(&block)
|
164
|
-
end
|
165
|
-
|
166
|
-
def ___is_a_stream?(thing)
|
167
|
-
!thing.kind_of?(::String) && thing.respond_to?(:<<)
|
168
|
-
end
|
169
|
-
|
170
|
-
def ___layout_arg?(args, block)
|
171
|
-
if args.size >= 2
|
172
|
-
true
|
173
|
-
elsif args.size <= 0
|
174
|
-
false
|
175
|
-
else # args.size == 1
|
176
|
-
!block.nil?
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
private
|
181
|
-
|
182
|
-
# you can't define locals that conflict with the template's public methods
|
183
|
-
def invalid_locals?(keys)
|
184
|
-
(keys.collect(&:to_s) & self.public_methods.collect(&:to_s)).size > 0
|
185
|
-
end
|
186
|
-
|
187
100
|
end
|
188
101
|
end
|
data/lib/undies/version.rb
CHANGED
data/lib/undies.rb
CHANGED
data/test/element_test.rb
CHANGED
@@ -1,116 +1,61 @@
|
|
1
|
-
require "
|
1
|
+
require "assert"
|
2
2
|
|
3
3
|
require "undies/element"
|
4
|
-
require "undies/element_stack"
|
5
4
|
require "undies/template"
|
6
5
|
|
7
6
|
class Undies::Element
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
context 'an element'
|
15
|
-
before { @e = Undies::Element.new(Undies::ElementStack.new, :div) }
|
8
|
+
class BasicTests < Assert::Context
|
9
|
+
desc 'an element'
|
10
|
+
before do
|
11
|
+
@e = Undies::Element.new(:div)
|
12
|
+
end
|
16
13
|
subject { @e }
|
17
|
-
|
18
|
-
should
|
14
|
+
|
15
|
+
should have_class_methods :html_attrs, :content, :flush
|
16
|
+
should have_instance_method :to_str
|
19
17
|
|
20
18
|
should "be a Node" do
|
21
19
|
assert_kind_of Undies::Node, subject
|
22
20
|
end
|
23
21
|
|
24
22
|
should "store it's name as a string" do
|
25
|
-
assert_equal "div", subject.
|
23
|
+
assert_equal "div", subject.instance_variable_get("@name")
|
26
24
|
end
|
27
25
|
|
28
|
-
should "have
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
should "have its nodes be its content" do
|
33
|
-
assert_equal subject.___nodes.object_id, subject.___content.object_id
|
34
|
-
end
|
35
|
-
|
36
|
-
should "have an element stack as its stack" do
|
37
|
-
assert_kind_of Undies::ElementStack, subject.send(:instance_variable_get, "@stack")
|
38
|
-
end
|
39
|
-
|
40
|
-
should "complain is not created with an ElementStack" do
|
41
|
-
assert_raises ArgumentError do
|
42
|
-
Undies::Element.new([], :div)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
class EmptyTest < Test::Unit::TestCase
|
51
|
-
include TestBelt
|
52
|
-
context 'an empty element'
|
53
|
-
before { @e = Undies::Element.new(Undies::ElementStack.new, :br) }
|
54
|
-
subject { @e }
|
55
|
-
|
56
|
-
should "have no nodes" do
|
57
|
-
assert_equal([], subject.___nodes)
|
26
|
+
should "have no content itself" do
|
27
|
+
assert_nil subject.class.content(subject)
|
58
28
|
end
|
59
29
|
|
60
30
|
end
|
61
31
|
|
62
|
-
|
63
|
-
|
64
|
-
class HtmlAttrsTest < BasicTest
|
65
|
-
context "html_attrs util"
|
32
|
+
class HtmlAttrsTest < BasicTests
|
33
|
+
desc "the element class html_attrs util"
|
66
34
|
|
67
35
|
should "convert an empty hash to html attrs" do
|
68
|
-
assert_equal
|
36
|
+
assert_equal '', Undies::Element.html_attrs({})
|
69
37
|
end
|
70
38
|
|
71
39
|
should "convert a basic hash to html attrs" do
|
72
|
-
attrs =
|
40
|
+
attrs = Undies::Element.html_attrs(:class => "test", :id => "test_1")
|
73
41
|
assert_match /^\s{1}/, attrs
|
74
42
|
assert attrs.include?('class="test"')
|
75
43
|
assert attrs.include?('id="test_1"')
|
76
44
|
end
|
77
45
|
|
78
46
|
should "convert a nested hash to html attrs" do
|
79
|
-
attrs =
|
47
|
+
attrs = Undies::Element.html_attrs({
|
80
48
|
:class => "testing", :id => "test_2",
|
81
49
|
:nested => {:something => 'is_awesome'}
|
82
50
|
})
|
83
51
|
assert_match /^\s{1}/, attrs
|
84
|
-
|
85
|
-
|
86
|
-
|
52
|
+
assert_included 'class="testing"', attrs
|
53
|
+
assert_included 'id="test_2"', attrs
|
54
|
+
assert_included 'nested_something="is_awesome"', attrs
|
87
55
|
end
|
88
56
|
end
|
89
57
|
|
90
|
-
|
91
|
-
|
92
|
-
class SerializeTest < BasicTest
|
93
|
-
should "serialize with no child elements" do
|
94
|
-
element = Undies::Element.new(Undies::ElementStack.new, :br)
|
95
|
-
assert_equal "<br />", element.to_s
|
96
|
-
end
|
97
|
-
|
98
|
-
should "serialize with attrs" do
|
99
|
-
element = Undies::Element.new(Undies::ElementStack.new, :br, {:class => 'big'})
|
100
|
-
assert_equal '<br class="big" />', element.to_s
|
101
|
-
end
|
102
|
-
|
103
|
-
should "serialize with attrs and content" do
|
104
|
-
templ = Undies::Template.new do
|
105
|
-
element(:strong, {:class => 'big'}) { __ "Loud Noises!" }
|
106
|
-
end
|
107
|
-
assert_equal '<strong class="big">Loud Noises!</strong>', templ.to_s
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
class CSSProxyTest < BasicTest
|
58
|
+
class CSSProxyTests < BasicTests
|
114
59
|
|
115
60
|
should "respond to any method ending in '!' as an id proxy" do
|
116
61
|
assert subject.respond_to?(:asdgasdg!)
|
@@ -119,32 +64,25 @@ class Undies::Element
|
|
119
64
|
should "proxy id attr with methods ending in '!'" do
|
120
65
|
assert_equal({
|
121
66
|
:id => 'thing1'
|
122
|
-
}, subject.thing1!.
|
123
|
-
end
|
124
|
-
|
125
|
-
should "nest elements from proxy id call" do
|
126
|
-
templ = Undies::Template.new do
|
127
|
-
element(:div).thing1! { _ "stuff" }
|
128
|
-
end
|
129
|
-
assert_equal "<div id=\"thing1\">stuff</div>", templ.to_s
|
67
|
+
}, subject.thing1!.instance_variable_get("@attrs"))
|
130
68
|
end
|
131
69
|
|
132
70
|
should "proxy id attr with last method call ending in '!'" do
|
133
71
|
assert_equal({
|
134
72
|
:id => 'thing2'
|
135
|
-
}, subject.thing1!.thing2!.
|
73
|
+
}, subject.thing1!.thing2!.instance_variable_get("@attrs"))
|
136
74
|
end
|
137
75
|
|
138
76
|
should "set id attr to explicit if called last " do
|
139
77
|
assert_equal({
|
140
78
|
:id => 'thing3'
|
141
|
-
}, subject.thing1!.thing2!(:id => 'thing3').
|
79
|
+
}, subject.thing1!.thing2!(:id => 'thing3').instance_variable_get("@attrs"))
|
142
80
|
end
|
143
81
|
|
144
82
|
should "set id attr to proxy if called last" do
|
145
83
|
assert_equal({
|
146
84
|
:id => 'thing1'
|
147
|
-
}, subject.thing2!(:id => 'thing3').thing1!.
|
85
|
+
}, subject.thing2!(:id => 'thing3').thing1!.instance_variable_get("@attrs"))
|
148
86
|
end
|
149
87
|
|
150
88
|
should "respond to any other method as a class proxy" do
|
@@ -154,32 +92,25 @@ class Undies::Element
|
|
154
92
|
should "proxy single html class attr" do
|
155
93
|
assert_equal({
|
156
94
|
:class => 'thing'
|
157
|
-
}, subject.thing.
|
158
|
-
end
|
159
|
-
|
160
|
-
should "nest elements from proxy class call" do
|
161
|
-
templ = Undies::Template.new do
|
162
|
-
element(:div).thing { _ "stuff" }
|
163
|
-
end
|
164
|
-
assert_equal "<div class=\"thing\">stuff</div>", templ.to_s
|
95
|
+
}, subject.thing.instance_variable_get("@attrs"))
|
165
96
|
end
|
166
97
|
|
167
98
|
should "proxy multi html class attrs" do
|
168
99
|
assert_equal({
|
169
100
|
:class => 'list thing awesome'
|
170
|
-
}, subject.list.thing.awesome.
|
101
|
+
}, subject.list.thing.awesome.instance_variable_get("@attrs"))
|
171
102
|
end
|
172
103
|
|
173
104
|
should "set class attr with explicit if called last " do
|
174
105
|
assert_equal({
|
175
106
|
:class => 'list'
|
176
|
-
}, subject.thing.awesome(:class => "list").
|
107
|
+
}, subject.thing.awesome(:class => "list").instance_variable_get("@attrs"))
|
177
108
|
end
|
178
109
|
|
179
110
|
should "update class attr with proxy if called last" do
|
180
111
|
assert_equal({
|
181
112
|
:class => 'list is good'
|
182
|
-
}, subject.thing.awesome(:class => "list is").good.
|
113
|
+
}, subject.thing.awesome(:class => "list is").good.instance_variable_get("@attrs"))
|
183
114
|
end
|
184
115
|
|
185
116
|
should "proxy mixed class and id selector attrs" do
|
@@ -189,11 +120,87 @@ class Undies::Element
|
|
189
120
|
}, subject.thing1!.awesome({
|
190
121
|
:class => "list is",
|
191
122
|
:id => "thing2"
|
192
|
-
}).good.thing3!.
|
123
|
+
}).good.thing3!.instance_variable_get("@attrs"))
|
124
|
+
end
|
125
|
+
|
126
|
+
should "not proxy if private methods are called" do
|
127
|
+
assert_equal "<div />", subject.send(:start_tag)
|
128
|
+
assert_equal nil, subject.send(:end_tag)
|
193
129
|
end
|
194
130
|
|
195
131
|
end
|
196
132
|
|
133
|
+
class SerializeTests < BasicTests
|
134
|
+
before do
|
135
|
+
@output = Undies::Output.new(StringIO.new(@out = ""))
|
136
|
+
end
|
137
|
+
|
138
|
+
should "serialize with no child elements" do
|
139
|
+
src = Undies::Source.new do
|
140
|
+
element(:br)
|
141
|
+
end
|
142
|
+
templ = Undies::Template.new(src, {}, @output)
|
143
|
+
assert_equal "<br />", @out
|
144
|
+
end
|
145
|
+
|
146
|
+
should "serialize with attrs" do
|
147
|
+
src = Undies::Source.new do
|
148
|
+
element(:br, :class => 'big')
|
149
|
+
end
|
150
|
+
templ = Undies::Template.new(src, {}, @output)
|
151
|
+
assert_equal '<br class="big" />', @out
|
152
|
+
end
|
197
153
|
|
154
|
+
should "serialize with attrs and content" do
|
155
|
+
src = Undies::Source.new do
|
156
|
+
element(:strong, {:class => 'big'}) { __ "Loud Noises!" }
|
157
|
+
end
|
158
|
+
templ = Undies::Template.new(src, {}, @output)
|
159
|
+
assert_equal '<strong class="big">Loud Noises!</strong>', @out
|
160
|
+
end
|
161
|
+
|
162
|
+
should "serialize element proxy id call" do
|
163
|
+
src = Undies::Source.new do
|
164
|
+
element(:div).thing1! { _ "stuff" }
|
165
|
+
end
|
166
|
+
templ = Undies::Template.new(src, {}, @output)
|
167
|
+
assert_equal "<div id=\"thing1\">stuff</div>", @out
|
168
|
+
end
|
169
|
+
|
170
|
+
should "serialize element proxy class call" do
|
171
|
+
src = Undies::Source.new do
|
172
|
+
element(:div).thing { _ "stuff" }
|
173
|
+
end
|
174
|
+
templ = Undies::Template.new(src, {}, @output)
|
175
|
+
assert_equal "<div class=\"thing\">stuff</div>", @out
|
176
|
+
end
|
177
|
+
|
178
|
+
should "serialize content from separate content blocks" do
|
179
|
+
src = Undies::Source.new do
|
180
|
+
element(:div){ _ "stuff" }.thing1!{ _ " and more stuff" }
|
181
|
+
end
|
182
|
+
templ = Undies::Template.new(src, {}, @output)
|
183
|
+
assert_equal "<div id=\"thing1\">stuff and more stuff</div>", @out
|
184
|
+
end
|
185
|
+
|
186
|
+
should "serialize nested elements with pp" do
|
187
|
+
output = Undies::Output.new(StringIO.new(@out = ""), :pp => 4)
|
188
|
+
src = Undies::Source.new do
|
189
|
+
element(:div) {
|
190
|
+
element(:span) { _ "Content!" }
|
191
|
+
__ "Raw"
|
192
|
+
element(:span) { _ "More content" }
|
193
|
+
}
|
194
|
+
end
|
195
|
+
templ = Undies::Template.new(src, {}, output)
|
196
|
+
assert_equal "
|
197
|
+
<div>
|
198
|
+
<span>Content!</span>
|
199
|
+
Raw
|
200
|
+
<span>More content</span>
|
201
|
+
</div>", @out
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
198
205
|
|
199
206
|
end
|
data/test/helper.rb
CHANGED
@@ -1,2 +1,4 @@
|
|
1
|
-
# this file is automatically required in when you require '
|
2
|
-
|
1
|
+
# this file is automatically required in when you require 'assert' in your tests
|
2
|
+
|
3
|
+
# add root dir to the load path
|
4
|
+
$LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
|
data/test/irb.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'assert/setup'
|
2
2
|
|
3
3
|
# this file is required in when the 'irb' rake test is run.
|
4
|
-
# b/c '
|
5
|
-
# be added to the LOAD_PATH and the test helper will be
|
4
|
+
# b/c 'assert' is required above, the test helper will be
|
6
5
|
# required in.
|
7
6
|
|
8
7
|
# put any IRB setup code here
|
9
8
|
|
10
|
-
require 'undies'
|
9
|
+
require 'undies'
|