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