undies 1.0.0 → 1.1.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 -1
- data/Gemfile.lock +3 -3
- data/README.rdoc +36 -2
- data/lib/undies/element.rb +5 -1
- data/lib/undies/element_stack.rb +35 -0
- data/lib/undies/node_list.rb +2 -2
- data/lib/undies/partial.rb +10 -7
- data/lib/undies/template.rb +70 -37
- data/lib/undies/version.rb +1 -1
- data/test/element_stack_test.rb +77 -0
- data/test/element_test.rb +20 -5
- data/test/helper.rb +2 -6
- data/test/irb.rb +10 -0
- data/test/node_list_test.rb +1 -1
- data/test/node_test.rb +1 -1
- data/test/partial_data_test.rb +1 -1
- data/test/partial_test.rb +24 -2
- data/test/source_test.rb +1 -1
- data/test/template_test.rb +48 -7
- data/undies.gemspec +4 -4
- metadata +20 -18
- data/test/env.rb +0 -10
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
undies (1.
|
4
|
+
undies (1.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
8
8
|
specs:
|
9
9
|
leftright (0.9.1)
|
10
10
|
rake (0.9.2)
|
11
|
-
test-belt (
|
11
|
+
test-belt (2.0.0)
|
12
12
|
leftright (~> 0.9.0)
|
13
13
|
|
14
14
|
PLATFORMS
|
@@ -17,5 +17,5 @@ PLATFORMS
|
|
17
17
|
DEPENDENCIES
|
18
18
|
bundler (~> 1.0)
|
19
19
|
rake (~> 0.9.2)
|
20
|
-
test-belt (~>
|
20
|
+
test-belt (~> 2.0)
|
21
21
|
undies!
|
data/README.rdoc
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
= Undies
|
2
|
-
A pure-Ruby DSL for writing HTML templates. Named for its gratuitous use of the underscore.
|
2
|
+
A pure-Ruby DSL for writing HTML or plain text templates. Named for its gratuitous use of the underscore.
|
3
3
|
== Installation
|
4
4
|
$ gem install undies
|
5
5
|
== Usage
|
@@ -32,9 +32,43 @@ Tag with class attributes
|
|
32
32
|
_h1.header.awesome
|
33
33
|
# => "<h1 class=\"header awesome\" />"
|
34
34
|
|
35
|
+
== Rendering Templates
|
36
|
+
|
37
|
+
* basic render:
|
38
|
+
|
39
|
+
# render a block of markup
|
40
|
+
Undies::Template.new do
|
41
|
+
_div {
|
42
|
+
_ "Some Content"
|
43
|
+
}
|
44
|
+
end.to_s
|
45
|
+
|
46
|
+
* streaming render
|
47
|
+
|
48
|
+
# render the template and push it to the output stream as it is being constructed
|
49
|
+
# just pass an IO to the template constructor
|
50
|
+
Undies::Template.new(output_io).new do
|
51
|
+
_div {
|
52
|
+
_ "Some Content"
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
* render passing local vars in and pretty printing:
|
57
|
+
|
58
|
+
# render a file with markup
|
59
|
+
# make the local vars 'four' and 'name' available the the template markup
|
60
|
+
# pretty print the output with 2-space indentation
|
61
|
+
Undies::Template.new("path/to/file", {
|
62
|
+
:four => 2 + 2,
|
63
|
+
:name => "Awesome"
|
64
|
+
}).to_s(2)
|
65
|
+
|
66
|
+
=== Pretty Printing
|
67
|
+
If you want to pretty print the output, pass an integer specifying the number of spaces to indent to the `to_s` method.
|
68
|
+
|
35
69
|
== License
|
36
70
|
|
37
|
-
Copyright (c) 2011 Kelly
|
71
|
+
Copyright (c) 2011 Kelly Redding
|
38
72
|
|
39
73
|
Permission is hereby granted, free of charge, to any person
|
40
74
|
obtaining a copy of this software and associated documentation
|
data/lib/undies/element.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'undies/node'
|
2
2
|
require 'undies/node_list'
|
3
|
+
require 'undies/element_stack'
|
3
4
|
|
4
5
|
module Undies
|
5
6
|
class Element < Node
|
@@ -8,6 +9,9 @@ module Undies
|
|
8
9
|
attr_accessor :nodes
|
9
10
|
|
10
11
|
def initialize(stack, name, attrs={}, &block)
|
12
|
+
if !stack.kind_of?(ElementStack)
|
13
|
+
raise ArgumentError, "stack must be an Undies::ElementStack"
|
14
|
+
end
|
11
15
|
super(@nodes = NodeList.new)
|
12
16
|
@stack = stack
|
13
17
|
@name = name.to_s
|
@@ -104,4 +108,4 @@ module Undies
|
|
104
108
|
end
|
105
109
|
|
106
110
|
end
|
107
|
-
end
|
111
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "undies/element"
|
2
|
+
|
3
|
+
module Undies
|
4
|
+
class ElementStack < ::Array
|
5
|
+
|
6
|
+
# an element stack is used to manage which element is receiving content
|
7
|
+
# if an undies template is streaming io, then when an element is pushed,
|
8
|
+
# its start tag is added to the stream and its end tag is added when popped.
|
9
|
+
|
10
|
+
attr_reader :io
|
11
|
+
|
12
|
+
def initialize(first_item=nil, io=nil, *args)
|
13
|
+
@io = io
|
14
|
+
# always initialize empty
|
15
|
+
super()
|
16
|
+
self.send(:<<, first_item) if first_item
|
17
|
+
end
|
18
|
+
|
19
|
+
def push(item)
|
20
|
+
unless item.kind_of?(Element)
|
21
|
+
raise ArgumentError, 'you can only push element nodes to an ElementStack'
|
22
|
+
end
|
23
|
+
super
|
24
|
+
@io << item.start_tag if @io
|
25
|
+
item
|
26
|
+
end
|
27
|
+
|
28
|
+
def pop
|
29
|
+
item = super
|
30
|
+
@io << item.end_tag if @io
|
31
|
+
item
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/undies/node_list.rb
CHANGED
data/lib/undies/partial.rb
CHANGED
@@ -4,16 +4,19 @@ require 'undies/template'
|
|
4
4
|
module Undies
|
5
5
|
class Partial < Template
|
6
6
|
|
7
|
-
def initialize(path,
|
8
|
-
|
9
|
-
|
10
|
-
super(path,
|
7
|
+
def initialize(path, *args)
|
8
|
+
locals = PartialData.new(path)
|
9
|
+
locals.values, io, locals.object = self.___partial_args(*args)
|
10
|
+
super(path, io, locals)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
protected
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def ___partial_args(*args)
|
16
|
+
[ args.last.kind_of?(::Hash) ? args.pop : {},
|
17
|
+
self.___is_a_stream?(args.last) ? args.pop : nil,
|
18
|
+
args.first
|
19
|
+
]
|
17
20
|
end
|
18
21
|
|
19
22
|
end
|
data/lib/undies/template.rb
CHANGED
@@ -8,34 +8,36 @@ module Undies
|
|
8
8
|
attr_accessor :nodes
|
9
9
|
|
10
10
|
def initialize(*args, &block)
|
11
|
-
|
12
|
-
|
13
|
-
self.
|
11
|
+
self.___locals, self.___io, source = self.___template_args(args, block)
|
12
|
+
self.___stack = ElementStack.new(self, self.___io)
|
13
|
+
self.nodes = NodeList.new
|
14
14
|
|
15
|
-
if (
|
16
|
-
instance_eval(
|
15
|
+
if (source).file?
|
16
|
+
instance_eval(source.data, source.source, 1)
|
17
17
|
else
|
18
|
-
instance_eval(
|
18
|
+
instance_eval(&source.data)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def to_s(pp_indent=nil)
|
23
|
-
|
23
|
+
self.nodes.collect{|n| n.to_s(0, pp_indent)}.join
|
24
24
|
end
|
25
25
|
|
26
26
|
# Add a text node (data escaped) to the nodes of the current node
|
27
|
-
def _(data)
|
28
|
-
|
27
|
+
def _(data="")
|
28
|
+
self.__ self.escape_html(data.to_s)
|
29
29
|
end
|
30
30
|
|
31
31
|
# Add a text node with the data un-escaped
|
32
|
-
def __(data)
|
33
|
-
|
32
|
+
def __(data="")
|
33
|
+
node = Node.new(data.to_s)
|
34
|
+
self.___io << node.to_s if self.___io
|
35
|
+
self.___add(node)
|
34
36
|
end
|
35
37
|
|
36
38
|
# Add an element to the nodes of the current node
|
37
39
|
def element(name, attrs={}, &block)
|
38
|
-
|
40
|
+
self.___add(Element.new(self.___stack, name, attrs, &block))
|
39
41
|
end
|
40
42
|
alias_method :tag, :element
|
41
43
|
|
@@ -59,56 +61,87 @@ module Undies
|
|
59
61
|
end
|
60
62
|
# ==============================================================
|
61
63
|
|
64
|
+
# Ripped from Rack v1.3.0 ======================================
|
65
|
+
# => ripped b/c I don't want a dependency on Rack for just this
|
66
|
+
ESCAPE_HTML = {
|
67
|
+
"&" => "&",
|
68
|
+
"<" => "<",
|
69
|
+
">" => ">",
|
70
|
+
"'" => "'",
|
71
|
+
'"' => """,
|
72
|
+
"/" => "/"
|
73
|
+
}
|
74
|
+
ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys)
|
75
|
+
|
76
|
+
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
77
|
+
def escape_html(string)
|
78
|
+
string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
|
79
|
+
end
|
80
|
+
# end Rip from Rack v1.3.0 =====================================
|
81
|
+
|
62
82
|
protected
|
63
83
|
|
64
|
-
|
65
|
-
|
84
|
+
# prefixing non-public methods with a triple underscore to not pollute
|
85
|
+
# metaclass locals scope
|
86
|
+
|
87
|
+
def ___locals=(data)
|
88
|
+
if !data.kind_of?(::Hash)
|
89
|
+
raise ArgumentError
|
90
|
+
end
|
91
|
+
if invalid_locals?(data.keys)
|
92
|
+
raise ArgumentError, "locals conflict with template's public methods."
|
93
|
+
end
|
66
94
|
data.each do |key, value|
|
67
|
-
|
95
|
+
self.___metaclass do
|
68
96
|
define_method(key) { value }
|
69
97
|
end
|
70
98
|
end
|
71
99
|
end
|
72
100
|
|
73
|
-
def
|
74
|
-
|
101
|
+
def ___add(node)
|
102
|
+
self.___stack.last.nodes.append(node)
|
75
103
|
end
|
76
104
|
|
77
|
-
def
|
105
|
+
def ___stack
|
78
106
|
@stack
|
79
107
|
end
|
80
108
|
|
81
|
-
|
109
|
+
def ___stack=(value)
|
110
|
+
raise ArgumentError if !value.respond_to?(:push) || !value.respond_to?(:pop)
|
111
|
+
@stack = value
|
112
|
+
end
|
82
113
|
|
83
|
-
def
|
114
|
+
def ___io
|
115
|
+
@io
|
116
|
+
end
|
117
|
+
|
118
|
+
def ___io=(value)
|
119
|
+
raise ArgumentError if value && !self.___is_a_stream?(value)
|
120
|
+
@io = value
|
121
|
+
end
|
122
|
+
|
123
|
+
def ___template_args(args, block)
|
84
124
|
[ args.last.kind_of?(::Hash) ? args.pop : {},
|
125
|
+
self.___is_a_stream?(args.last) ? args.pop : nil,
|
85
126
|
Source.new(block || args.first.to_s)
|
86
127
|
]
|
87
128
|
end
|
88
129
|
|
89
|
-
def
|
130
|
+
def ___metaclass(&block)
|
90
131
|
metaclass = class << self; self; end
|
91
132
|
metaclass.class_eval(&block)
|
92
133
|
end
|
93
134
|
|
94
|
-
|
95
|
-
|
96
|
-
ESCAPE_HTML = {
|
97
|
-
"&" => "&",
|
98
|
-
"<" => "<",
|
99
|
-
">" => ">",
|
100
|
-
"'" => "'",
|
101
|
-
'"' => """,
|
102
|
-
"/" => "/"
|
103
|
-
}
|
104
|
-
ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys)
|
105
|
-
|
106
|
-
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
107
|
-
def escape_html(string)
|
108
|
-
string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
|
135
|
+
def ___is_a_stream?(thing)
|
136
|
+
!thing.kind_of?(::String) && thing.respond_to?(:<<)
|
109
137
|
end
|
110
|
-
# end Rip from Rack v1.3.0 =====================================
|
111
138
|
|
139
|
+
private
|
140
|
+
|
141
|
+
# you can't define locals that conflict with the template's public methods
|
142
|
+
def invalid_locals?(keys)
|
143
|
+
(keys.collect(&:to_s) & self.public_methods.collect(&:to_s)).size > 0
|
144
|
+
end
|
112
145
|
|
113
146
|
end
|
114
147
|
end
|
data/lib/undies/version.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
require "test_belt"
|
2
|
+
|
3
|
+
require "stringio"
|
4
|
+
require "undies/element_stack"
|
5
|
+
require "undies/node"
|
6
|
+
|
7
|
+
class Undies::ElementStack
|
8
|
+
|
9
|
+
class BasicTest < Test::Unit::TestCase
|
10
|
+
include TestBelt
|
11
|
+
|
12
|
+
context 'an element stack'
|
13
|
+
before { @es = Undies::ElementStack.new }
|
14
|
+
subject { @es }
|
15
|
+
|
16
|
+
should have_instance_method :push, :pop
|
17
|
+
should have_reader :io
|
18
|
+
|
19
|
+
should "be an Array" do
|
20
|
+
assert_kind_of Array, subject
|
21
|
+
end
|
22
|
+
|
23
|
+
should "empty by default" do
|
24
|
+
assert subject.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
should "compain when trying to push non-elements" do
|
28
|
+
assert_raises ArgumentError do
|
29
|
+
subject.push Undies::Node.new
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_nothing_raised do
|
33
|
+
subject << 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
should "initialize with a first item if one is given" do
|
38
|
+
stack = Undies::ElementStack.new(12)
|
39
|
+
assert_equal [12], stack
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
class StreamingTest < BasicTest
|
45
|
+
context "when streaming"
|
46
|
+
before do
|
47
|
+
@output = ""
|
48
|
+
@outstream = StringIO.new(@output)
|
49
|
+
@es = Undies::ElementStack.new(nil, @outstream)
|
50
|
+
end
|
51
|
+
|
52
|
+
should "know its stream" do
|
53
|
+
assert_same @outstream, subject.io
|
54
|
+
end
|
55
|
+
|
56
|
+
should "stream an elements start tag when that element is pushed" do
|
57
|
+
subject.push(Undies::Element.new(Undies::ElementStack.new, "div") {})
|
58
|
+
assert_equal "<div>", @output
|
59
|
+
end
|
60
|
+
|
61
|
+
should "stream an elements end tag when that element is popped" do
|
62
|
+
elem = Undies::Element.new(Undies::ElementStack.new, "div") {}
|
63
|
+
subject.push(elem)
|
64
|
+
popped_elem = subject.pop
|
65
|
+
assert_equal "<div></div>", @output
|
66
|
+
assert_same elem, popped_elem
|
67
|
+
end
|
68
|
+
|
69
|
+
should "stream an element with no content when pushed/popped" do
|
70
|
+
subject.push(Undies::Element.new(Undies::ElementStack.new, "span"))
|
71
|
+
subject.pop
|
72
|
+
assert_equal "<span />", @output
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/test/element_test.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
require "
|
1
|
+
require "test_belt"
|
2
|
+
|
2
3
|
require "undies/element"
|
4
|
+
require "undies/element_stack"
|
5
|
+
require "undies/template"
|
3
6
|
|
4
7
|
class Undies::Element
|
5
8
|
|
@@ -9,7 +12,8 @@ class Undies::Element
|
|
9
12
|
include TestBelt
|
10
13
|
|
11
14
|
context 'an element'
|
12
|
-
|
15
|
+
before { @e = Undies::Element.new(Undies::ElementStack.new, :div) }
|
16
|
+
subject { @e }
|
13
17
|
should have_readers :name, :attrs
|
14
18
|
should have_accessor :nodes
|
15
19
|
|
@@ -29,6 +33,16 @@ class Undies::Element
|
|
29
33
|
assert_equal subject.nodes.object_id, subject.content.object_id
|
30
34
|
end
|
31
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
|
+
|
32
46
|
end
|
33
47
|
|
34
48
|
|
@@ -36,7 +50,8 @@ class Undies::Element
|
|
36
50
|
class EmptyTest < Test::Unit::TestCase
|
37
51
|
include TestBelt
|
38
52
|
context 'an empty element'
|
39
|
-
|
53
|
+
before { @e = Undies::Element.new(Undies::ElementStack.new, :br) }
|
54
|
+
subject { @e }
|
40
55
|
|
41
56
|
should "have no nodes" do
|
42
57
|
assert_equal([], subject.nodes)
|
@@ -76,12 +91,12 @@ class Undies::Element
|
|
76
91
|
|
77
92
|
class SerializeTest < BasicTest
|
78
93
|
should "serialize with no child elements" do
|
79
|
-
element = Undies::Element.new(
|
94
|
+
element = Undies::Element.new(Undies::ElementStack.new, :br)
|
80
95
|
assert_equal "<br />", element.to_s
|
81
96
|
end
|
82
97
|
|
83
98
|
should "serialize with attrs" do
|
84
|
-
element = Undies::Element.new(
|
99
|
+
element = Undies::Element.new(Undies::ElementStack.new, :br, {:class => 'big'})
|
85
100
|
assert_equal '<br class="big" />', element.to_s
|
86
101
|
end
|
87
102
|
|
data/test/helper.rb
CHANGED
data/test/irb.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'test_belt'
|
2
|
+
|
3
|
+
# this file is required in when the 'irb' rake test is run.
|
4
|
+
# b/c 'test_belt' is required above, lib and test dirs will
|
5
|
+
# be added to the LOAD_PATH and the test helper will be
|
6
|
+
# required in.
|
7
|
+
|
8
|
+
# put any IRB setup code here
|
9
|
+
|
10
|
+
require 'undies'
|
data/test/node_list_test.rb
CHANGED
data/test/node_test.rb
CHANGED
data/test/partial_data_test.rb
CHANGED
data/test/partial_test.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
require "
|
1
|
+
require "test_belt"
|
2
|
+
|
3
|
+
require "stringio"
|
2
4
|
require "undies/partial"
|
3
5
|
|
4
6
|
class Undies::Partial
|
@@ -7,7 +9,11 @@ class Undies::Partial
|
|
7
9
|
include TestBelt
|
8
10
|
|
9
11
|
context 'partial'
|
10
|
-
|
12
|
+
before do
|
13
|
+
@path = 'test/templates/test.html.rb'
|
14
|
+
@p = Undies::Partial.new @path
|
15
|
+
end
|
16
|
+
subject { @p }
|
11
17
|
|
12
18
|
should "be a kind of Template" do
|
13
19
|
assert subject.kind_of?(Undies::Template)
|
@@ -38,4 +44,20 @@ class Undies::Partial
|
|
38
44
|
|
39
45
|
end
|
40
46
|
|
47
|
+
class StreamTest < BasicTest
|
48
|
+
context "that is streaming"
|
49
|
+
|
50
|
+
before do
|
51
|
+
@output = ""
|
52
|
+
@outstream = StringIO.new(@output)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
should "should write to the stream as its being constructed" do
|
57
|
+
Undies::Partial.new @path, @outstream
|
58
|
+
assert_equal "<html><head></head><body><div class=\"file\">FILE!!</div></body></html>", @output
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
41
63
|
end
|
data/test/source_test.rb
CHANGED
data/test/template_test.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
require "
|
1
|
+
require "test_belt"
|
2
|
+
|
3
|
+
require "stringio"
|
2
4
|
require "undies/template"
|
3
5
|
|
4
6
|
class Undies::Template
|
@@ -8,7 +10,7 @@ class Undies::Template
|
|
8
10
|
|
9
11
|
context 'a template'
|
10
12
|
subject { Undies::Template.new {} }
|
11
|
-
should have_instance_method :to_s
|
13
|
+
should have_instance_method :to_s, :escape_html
|
12
14
|
should have_instance_methods :_, :__, :element, :tag
|
13
15
|
should have_accessor :nodes
|
14
16
|
|
@@ -16,6 +18,10 @@ class Undies::Template
|
|
16
18
|
assert_kind_of Undies::NodeList, subject.nodes
|
17
19
|
end
|
18
20
|
|
21
|
+
should "have no io stream by default" do
|
22
|
+
assert_nil subject.send(:___io)
|
23
|
+
end
|
24
|
+
|
19
25
|
end
|
20
26
|
|
21
27
|
|
@@ -46,6 +52,11 @@ class Undies::Template
|
|
46
52
|
assert_equal subject.send(:escape_html, @data), subject._(@data).to_s
|
47
53
|
end
|
48
54
|
|
55
|
+
should "add empty string nodes using '__' and '_' methods with no args" do
|
56
|
+
assert_equal "", subject._.to_s
|
57
|
+
assert_equal "", subject.__.to_s
|
58
|
+
end
|
59
|
+
|
49
60
|
end
|
50
61
|
|
51
62
|
|
@@ -54,7 +65,7 @@ class Undies::Template
|
|
54
65
|
context "using the 'element' helper"
|
55
66
|
|
56
67
|
should "return an Element object" do
|
57
|
-
assert_equal Undies::Element.new(
|
68
|
+
assert_equal Undies::Element.new(Undies::ElementStack.new, :br), subject.element(:br)
|
58
69
|
end
|
59
70
|
|
60
71
|
should "alias it with 'tag'" do
|
@@ -64,7 +75,7 @@ class Undies::Template
|
|
64
75
|
should "add a new Element object" do
|
65
76
|
subject.element(:br)
|
66
77
|
assert_equal 1, subject.nodes.size
|
67
|
-
assert_equal Undies::Element.new(
|
78
|
+
assert_equal Undies::Element.new(Undies::ElementStack.new, :br), subject.nodes.first
|
68
79
|
end
|
69
80
|
|
70
81
|
should "respond to underscore-prefix methods" do
|
@@ -86,7 +97,7 @@ class Undies::Template
|
|
86
97
|
|
87
98
|
|
88
99
|
|
89
|
-
class
|
100
|
+
class LocalsTest < BasicTest
|
90
101
|
|
91
102
|
should "only accept the data if it is a Hash" do
|
92
103
|
assert_raises NoMethodError do
|
@@ -105,7 +116,13 @@ class Undies::Template
|
|
105
116
|
)
|
106
117
|
end
|
107
118
|
|
108
|
-
should "
|
119
|
+
should "complain if trying to set locals that conflict with public methods" do
|
120
|
+
assert_raises ArgumentError do
|
121
|
+
Undies::Template.new(:_ => "yay!") {}
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
should "respond to each locals key with its value" do
|
109
126
|
templ = Undies::Template.new(:some => "data") {}
|
110
127
|
assert_equal "data", templ.some
|
111
128
|
end
|
@@ -127,7 +144,7 @@ class Undies::Template
|
|
127
144
|
assert_equal "<div><div>#{templ.object_id}</div></div>", templ.to_s
|
128
145
|
end
|
129
146
|
|
130
|
-
should "be able to access its
|
147
|
+
should "be able to access its locals in the template definition" do
|
131
148
|
templ = Undies::Template.new(:name => "awesome") do
|
132
149
|
_div {
|
133
150
|
_div { _ name }
|
@@ -178,4 +195,28 @@ class Undies::Template
|
|
178
195
|
end
|
179
196
|
end
|
180
197
|
|
198
|
+
|
199
|
+
|
200
|
+
class StreamTest < BasicTest
|
201
|
+
context "that is streaming"
|
202
|
+
|
203
|
+
before do
|
204
|
+
@output = ""
|
205
|
+
@outstream = StringIO.new(@output)
|
206
|
+
end
|
207
|
+
|
208
|
+
should "should write to the stream as its being constructed" do
|
209
|
+
templ = Undies::Template.new(@outstream) do
|
210
|
+
_div {
|
211
|
+
_div.good.thing!(:type => "something") {
|
212
|
+
__ "good streaming action"
|
213
|
+
}
|
214
|
+
}
|
215
|
+
end
|
216
|
+
assert_equal "<div><div class=\"good\" id=\"thing\" type=\"something\">good streaming action</div></div>", @output
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
181
221
|
end
|
222
|
+
|
data/undies.gemspec
CHANGED
@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "undies"
|
7
7
|
s.version = Undies::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Kelly
|
9
|
+
s.authors = ["Kelly Redding"]
|
10
10
|
s.email = ["kelly@kelredd.com"]
|
11
11
|
s.homepage = "http://github.com/kelredd/undies"
|
12
|
-
s.summary = %q{A pure-Ruby HTML templating DSL.}
|
13
|
-
s.description = %q{A pure-Ruby HTML templating DSL.}
|
12
|
+
s.summary = %q{A pure-Ruby HTML and plain text templating DSL.}
|
13
|
+
s.description = %q{A pure-Ruby HTML and plain text templating DSL.}
|
14
14
|
|
15
15
|
s.files = `git ls-files`.split("\n")
|
16
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -18,6 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
20
|
s.add_development_dependency("bundler", ["~> 1.0"])
|
21
|
-
s.add_development_dependency("test-belt", ["~>
|
21
|
+
s.add_development_dependency("test-belt", ["~> 2.0"])
|
22
22
|
|
23
23
|
end
|
metadata
CHANGED
@@ -1,23 +1,25 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: undies
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
|
-
- Kelly
|
13
|
+
- Kelly Redding
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-09-08 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
21
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
22
24
|
none: false
|
23
25
|
requirements:
|
@@ -29,26 +31,23 @@ dependencies:
|
|
29
31
|
- 0
|
30
32
|
version: "1.0"
|
31
33
|
version_requirements: *id001
|
32
|
-
prerelease: false
|
33
34
|
name: bundler
|
34
|
-
type: :development
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
36
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
37
39
|
none: false
|
38
40
|
requirements:
|
39
41
|
- - ~>
|
40
42
|
- !ruby/object:Gem::Version
|
41
|
-
hash:
|
43
|
+
hash: 3
|
42
44
|
segments:
|
43
|
-
-
|
44
|
-
- 1
|
45
|
+
- 2
|
45
46
|
- 0
|
46
|
-
version:
|
47
|
+
version: "2.0"
|
47
48
|
version_requirements: *id002
|
48
|
-
prerelease: false
|
49
49
|
name: test-belt
|
50
|
-
|
51
|
-
description: A pure-Ruby HTML templating DSL.
|
50
|
+
description: A pure-Ruby HTML and plain text templating DSL.
|
52
51
|
email:
|
53
52
|
- kelly@kelredd.com
|
54
53
|
executables: []
|
@@ -65,6 +64,7 @@ files:
|
|
65
64
|
- Rakefile
|
66
65
|
- lib/undies.rb
|
67
66
|
- lib/undies/element.rb
|
67
|
+
- lib/undies/element_stack.rb
|
68
68
|
- lib/undies/node.rb
|
69
69
|
- lib/undies/node_list.rb
|
70
70
|
- lib/undies/partial.rb
|
@@ -72,9 +72,10 @@ files:
|
|
72
72
|
- lib/undies/source.rb
|
73
73
|
- lib/undies/template.rb
|
74
74
|
- lib/undies/version.rb
|
75
|
+
- test/element_stack_test.rb
|
75
76
|
- test/element_test.rb
|
76
|
-
- test/env.rb
|
77
77
|
- test/helper.rb
|
78
|
+
- test/irb.rb
|
78
79
|
- test/node_list_test.rb
|
79
80
|
- test/node_test.rb
|
80
81
|
- test/partial_data_test.rb
|
@@ -113,14 +114,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
114
|
requirements: []
|
114
115
|
|
115
116
|
rubyforge_project:
|
116
|
-
rubygems_version: 1.
|
117
|
+
rubygems_version: 1.8.10
|
117
118
|
signing_key:
|
118
119
|
specification_version: 3
|
119
|
-
summary: A pure-Ruby HTML templating DSL.
|
120
|
+
summary: A pure-Ruby HTML and plain text templating DSL.
|
120
121
|
test_files:
|
122
|
+
- test/element_stack_test.rb
|
121
123
|
- test/element_test.rb
|
122
|
-
- test/env.rb
|
123
124
|
- test/helper.rb
|
125
|
+
- test/irb.rb
|
124
126
|
- test/node_list_test.rb
|
125
127
|
- test/node_test.rb
|
126
128
|
- test/partial_data_test.rb
|
data/test/env.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# Add test and lib paths to the $LOAD_PATH
|
2
|
-
[ File.dirname(__FILE__),
|
3
|
-
File.join(File.dirname(__FILE__), '..', 'lib')
|
4
|
-
].each do |path|
|
5
|
-
full_path = File.expand_path(path)
|
6
|
-
$LOAD_PATH.unshift(full_path) unless $LOAD_PATH.include?(full_path)
|
7
|
-
end
|
8
|
-
|
9
|
-
require 'undies'
|
10
|
-
|