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
@@ -0,0 +1,91 @@
|
|
1
|
+
require "assert"
|
2
|
+
|
3
|
+
require "undies/named_source"
|
4
|
+
|
5
|
+
class Undies::NamedSource
|
6
|
+
|
7
|
+
class BasicTests < Assert::Context
|
8
|
+
desc 'a named source'
|
9
|
+
before do
|
10
|
+
@content_file = File.expand_path('test/templates/content.html.rb')
|
11
|
+
@content_file_data = File.read(@content_file)
|
12
|
+
@content_file_nsource = Undies::NamedSource.new(@content_file)
|
13
|
+
@content_file_source = Undies::Source.new(@content_file)
|
14
|
+
@hi_proc = Proc.new do
|
15
|
+
_div { _ "Hi!" }
|
16
|
+
end
|
17
|
+
@hi_proc_nsource = Undies::NamedSource.new(&@hi_proc)
|
18
|
+
|
19
|
+
@s = Undies::NamedSource.new() {}
|
20
|
+
end
|
21
|
+
subject { @s }
|
22
|
+
|
23
|
+
should have_accessors :file, :opts, :proc, :args
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class AccessorTests < BasicTests
|
28
|
+
before do
|
29
|
+
subject.file = @content_file
|
30
|
+
subject.opts = {:layout => :another}
|
31
|
+
subject.proc = @hi_proc
|
32
|
+
@subject_args = [@content_file, {:layout => :another}, @hi_proc]
|
33
|
+
|
34
|
+
@another = Undies::NamedSource.new(@content_file, &@hi_proc)
|
35
|
+
@another_args = [@content_file, {}, @hi_proc]
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
should "write its accessors" do
|
40
|
+
assert_equal @content_file, subject.file
|
41
|
+
assert_equal({:layout => :another}, subject.opts)
|
42
|
+
assert_equal @hi_proc, subject.proc
|
43
|
+
|
44
|
+
assert_equal @content_file, @another.file
|
45
|
+
assert_equal({}, @another.opts)
|
46
|
+
assert_equal @hi_proc, @another.proc
|
47
|
+
end
|
48
|
+
|
49
|
+
should "build its args from its accessors" do
|
50
|
+
assert_equal @subject_args, subject.args
|
51
|
+
assert_equal @another_args, @another.args
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class UndiesTests < BasicTests
|
57
|
+
before do
|
58
|
+
Undies.named_sources.clear
|
59
|
+
end
|
60
|
+
after do
|
61
|
+
Undies.named_sources.clear
|
62
|
+
end
|
63
|
+
|
64
|
+
should "provide a singleton method for accessing named sources" do
|
65
|
+
assert_respond_to :named_sources, Undies
|
66
|
+
assert_respond_to :named_source, Undies
|
67
|
+
assert_respond_to :source, Undies
|
68
|
+
end
|
69
|
+
|
70
|
+
should "access the singleton set of named sources" do
|
71
|
+
assert_equal({}, Undies.named_sources)
|
72
|
+
end
|
73
|
+
|
74
|
+
should "build new and retrieve named sources from the singleton" do
|
75
|
+
assert_equal @content_file_nsource, Undies.named_source(:cf, @content_file)
|
76
|
+
assert_equal @content_file_nsource, Undies.named_source(:cf)
|
77
|
+
end
|
78
|
+
|
79
|
+
should "build retrieve sources from the source singleton accessor" do
|
80
|
+
Undies.named_source(:cf, @content_file)
|
81
|
+
assert_equal @content_file_source, Undies.source(:cf)
|
82
|
+
end
|
83
|
+
|
84
|
+
should "not retrieve unknown named sources" do
|
85
|
+
assert_nil Undies.named_source(:wtf)
|
86
|
+
assert_nil Undies.source(:wtf)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "assert"
|
2
|
+
|
3
|
+
require "stringio"
|
4
|
+
require "undies/node"
|
5
|
+
require "undies/element"
|
6
|
+
require "undies/node_buffer"
|
7
|
+
|
8
|
+
class Undies::NodeStack
|
9
|
+
|
10
|
+
class BasicTests < Assert::Context
|
11
|
+
desc 'a node buffer'
|
12
|
+
before do
|
13
|
+
@nb = Undies::NodeBuffer.new
|
14
|
+
end
|
15
|
+
subject { @nb }
|
16
|
+
|
17
|
+
should have_instance_method :push, :pull, :flush
|
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
|
+
end
|
28
|
+
|
29
|
+
class PushPullFlushTests < BasicTests
|
30
|
+
before do
|
31
|
+
@stream_test_output = Undies::Output.new(@outstream = StringIO.new(@out = ""))
|
32
|
+
end
|
33
|
+
|
34
|
+
should "flush nodes" do
|
35
|
+
node = Undies::Node.new("lala")
|
36
|
+
subject.push(node); subject.pull(@stream_test_output)
|
37
|
+
assert_equal "lala", @out
|
38
|
+
end
|
39
|
+
|
40
|
+
should "flush elements with no content" do
|
41
|
+
elem = Undies::Element.new("span")
|
42
|
+
subject.push(elem); subject.pull(@stream_test_output)
|
43
|
+
assert_equal "<span />", @out
|
44
|
+
end
|
45
|
+
|
46
|
+
should "flush elements with content" do
|
47
|
+
elem = Undies::Element.new("div") {}
|
48
|
+
subject.push(elem); subject.pull(@stream_test_output)
|
49
|
+
assert_equal "<div></div>", @out
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/test/node_test.rb
CHANGED
@@ -1,22 +1,31 @@
|
|
1
|
-
require "
|
1
|
+
require "assert"
|
2
|
+
|
2
3
|
require "undies/node"
|
4
|
+
require "undies/node_buffer"
|
3
5
|
|
4
6
|
class Undies::Node
|
5
7
|
|
6
|
-
class
|
7
|
-
|
8
|
+
class BasicTests < Assert::Context
|
9
|
+
desc 'a node'
|
10
|
+
before { @n = Undies::Node.new("a text node here") }
|
11
|
+
subject { @n }
|
8
12
|
|
9
|
-
|
10
|
-
subject { Undies::Node.new("a text node here") }
|
11
|
-
should have_instance_method :to_s, :start_tag, :end_tag
|
12
|
-
should have_reader :___content
|
13
|
+
should have_class_methods :content, :flush
|
13
14
|
|
14
15
|
should "know it's content" do
|
15
|
-
assert_equal "a text node here", subject.
|
16
|
+
assert_equal "a text node here", subject.class.content(subject)
|
17
|
+
end
|
18
|
+
|
19
|
+
should "know it's start/end tags" do
|
20
|
+
assert_nil subject.instance_variable_get("@start_tag")
|
21
|
+
assert_nil subject.instance_variable_get("@end_tag")
|
16
22
|
end
|
17
23
|
|
18
|
-
should "
|
19
|
-
|
24
|
+
should "output its content when flushed" do
|
25
|
+
output = Undies::Output.new(StringIO.new(out = ""))
|
26
|
+
subject.class.flush(output, subject)
|
27
|
+
|
28
|
+
assert_equal "a text node here", out
|
20
29
|
end
|
21
30
|
|
22
31
|
end
|
data/test/output_test.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require "assert"
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
require "undies/output"
|
5
|
+
|
6
|
+
class Undies::Output
|
7
|
+
|
8
|
+
class BasicTests < Assert::Context
|
9
|
+
desc 'render data'
|
10
|
+
before do
|
11
|
+
@io = StringIO.new(@out = "")
|
12
|
+
@output = Undies::Output.new(@io)
|
13
|
+
end
|
14
|
+
subject { @output }
|
15
|
+
|
16
|
+
should have_readers :io, :options, :pp, :node_buffer
|
17
|
+
should have_instance_methods :options=, :<<, :pp_level
|
18
|
+
should have_instance_methods :node, :element, :flush
|
19
|
+
|
20
|
+
should "know its stream" do
|
21
|
+
assert_same @io, subject.io
|
22
|
+
end
|
23
|
+
|
24
|
+
# TODO: switch to call it a node buffer
|
25
|
+
should "have an empty node buffer" do
|
26
|
+
assert_kind_of Undies::NodeBuffer, subject.node_buffer
|
27
|
+
assert_equal 0, subject.node_buffer.size
|
28
|
+
end
|
29
|
+
|
30
|
+
should "default to no pretty printing" do
|
31
|
+
assert_nil subject.pp
|
32
|
+
end
|
33
|
+
|
34
|
+
should "default to pretty printing level 0" do
|
35
|
+
assert_equal 0, subject.pp_level
|
36
|
+
end
|
37
|
+
|
38
|
+
should "stream data" do
|
39
|
+
subject << "some data"
|
40
|
+
assert_equal @out, "some data"
|
41
|
+
end
|
42
|
+
|
43
|
+
should "not stream nil data" do
|
44
|
+
subject << nil
|
45
|
+
assert_equal @out, ""
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
class PrettyPrintTests < BasicTests
|
51
|
+
desc "when pretty printing"
|
52
|
+
before do
|
53
|
+
subject.options = {:pp => 2}
|
54
|
+
end
|
55
|
+
|
56
|
+
should "know its pp indent amount" do
|
57
|
+
assert_equal 2, subject.pp
|
58
|
+
end
|
59
|
+
|
60
|
+
should "pretty print stream data" do
|
61
|
+
subject << "some data"
|
62
|
+
assert_equal "\nsome data", @out
|
63
|
+
|
64
|
+
subject.pp_level +=1
|
65
|
+
subject << "indented data"
|
66
|
+
assert_equal "\nsome data\n indented data", @out
|
67
|
+
|
68
|
+
subject.pp_level -= 1
|
69
|
+
subject << "more data"
|
70
|
+
assert_equal "\nsome data\n indented data\nmore data", @out
|
71
|
+
end
|
72
|
+
|
73
|
+
should "pretty print nodes" do
|
74
|
+
subject.node("lala"); subject.flush
|
75
|
+
assert_equal "\nlala", @out
|
76
|
+
end
|
77
|
+
|
78
|
+
should "pretty print elements with no content" do
|
79
|
+
subject.element("span"); subject.flush
|
80
|
+
assert_equal "\n<span />", @out
|
81
|
+
end
|
82
|
+
|
83
|
+
should "pretty print elements with content" do
|
84
|
+
subject.element("div") {}; subject.flush
|
85
|
+
assert_equal "\n<div></div>", @out
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
class NodeHandlingTests < BasicTests
|
92
|
+
before do
|
93
|
+
@hey = Undies::Node.new "hey!"
|
94
|
+
|
95
|
+
src = Undies::Source.new do
|
96
|
+
_div.good.thing!(:type => "something") {
|
97
|
+
__ "action"
|
98
|
+
}
|
99
|
+
end
|
100
|
+
@expected_output = "hey!"
|
101
|
+
end
|
102
|
+
|
103
|
+
should "create and append nodes" do
|
104
|
+
assert_equal @hey, subject.node("hey!")
|
105
|
+
assert_equal 1, subject.node_buffer.size
|
106
|
+
end
|
107
|
+
|
108
|
+
should "create and append elements" do
|
109
|
+
elem = Undies::Element.new(:div)
|
110
|
+
assert_equal elem, subject.element(:div)
|
111
|
+
assert_equal 1, subject.node_buffer.size
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "assert"
|
2
|
+
|
3
|
+
require "undies/source_stack"
|
4
|
+
|
5
|
+
class Undies::SourceStack
|
6
|
+
|
7
|
+
class BasicTests < Assert::Context
|
8
|
+
desc 'a source stack'
|
9
|
+
before do
|
10
|
+
@content_file = File.expand_path('test/templates/content.html.rb')
|
11
|
+
@content_file_source = Undies::Source.new(@content_file)
|
12
|
+
|
13
|
+
@hi_proc = Proc.new do
|
14
|
+
_div { _ "Hi!" }
|
15
|
+
end
|
16
|
+
@hi_proc_source = Undies::Source.new(&@hi_proc)
|
17
|
+
@hi_proc_content_file_source = Undies::Source.new({:layout => @content_file}, &@hi_proc)
|
18
|
+
|
19
|
+
@ss = Undies::SourceStack.new(@hi_proc_content_file_source)
|
20
|
+
end
|
21
|
+
subject { @ss }
|
22
|
+
|
23
|
+
should have_instance_method :pop
|
24
|
+
|
25
|
+
should "be an Array" do
|
26
|
+
assert_kind_of Array, subject
|
27
|
+
end
|
28
|
+
|
29
|
+
should "base itself on the source" do
|
30
|
+
assert_equal @hi_proc_content_file_source, subject.first
|
31
|
+
assert_equal @hi_proc_source, Undies::SourceStack.new(@hi_proc_source).first
|
32
|
+
end
|
33
|
+
|
34
|
+
should "should stack on the source's layouts" do
|
35
|
+
assert_equal @content_file_source, subject.last
|
36
|
+
|
37
|
+
content = Undies::Source.new(@content_file, {
|
38
|
+
:layout => (lay1 = Undies::Source.new(@content_file, {
|
39
|
+
:layout => (lay2 = Undies::Source.new(@content_file))
|
40
|
+
}))
|
41
|
+
})
|
42
|
+
|
43
|
+
assert_equal [content, lay1, lay2], Undies::SourceStack.new(content)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/test/source_test.rb
CHANGED
@@ -1,49 +1,153 @@
|
|
1
|
-
require "
|
1
|
+
require "assert"
|
2
|
+
|
2
3
|
require "undies/source"
|
3
4
|
|
4
5
|
class Undies::Source
|
5
6
|
|
6
|
-
class
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
should have_instance_method :file?
|
7
|
+
class BasicTests < Assert::Context
|
8
|
+
desc 'a source'
|
9
|
+
before do
|
10
|
+
@content_file = File.expand_path('test/templates/content.html.rb')
|
11
|
+
@content_file_data = File.read(@content_file)
|
12
|
+
@content_file_source = Undies::Source.new(@content_file)
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
Undies::Source.new
|
14
|
+
@hi_proc = Proc.new do
|
15
|
+
_div { _ "Hi!" }
|
17
16
|
end
|
17
|
+
@hi_proc_source = Undies::Source.new(&@hi_proc)
|
18
|
+
|
19
|
+
@named_source_name = :cf
|
20
|
+
@named_source = Undies.named_source(@named_source_name, @content_file)
|
21
|
+
@named_source_source = Undies.source(@named_source_name)
|
22
|
+
|
23
|
+
@s = Undies::Source.new {}
|
18
24
|
end
|
25
|
+
subject { @s }
|
19
26
|
|
20
|
-
should
|
21
|
-
|
22
|
-
|
23
|
-
|
27
|
+
should have_readers :source, :data, :layout
|
28
|
+
should have_writers :args, :source, :layout
|
29
|
+
should have_instance_method :file?, :layouts, :layout_sources
|
30
|
+
|
31
|
+
should "know whether its a file source or not" do
|
32
|
+
assert @content_file_source.file?
|
33
|
+
assert_not @hi_proc_source.file?
|
24
34
|
end
|
25
35
|
|
26
36
|
end
|
27
37
|
|
28
|
-
class
|
29
|
-
|
30
|
-
|
38
|
+
class SourceWriterTests < BasicTests
|
39
|
+
before do
|
40
|
+
@does_not_exist_path = '/path/does/not/exist'
|
41
|
+
end
|
42
|
+
|
43
|
+
should "write its source value" do
|
44
|
+
subject.source = @hi_proc
|
45
|
+
assert_equal @hi_proc, subject.source
|
46
|
+
assert_equal @content_file, (subject.source = @content_file)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "complain if writing a nil source" do
|
50
|
+
assert_raises(ArgumentError) { subject.source = nil }
|
51
|
+
end
|
52
|
+
|
53
|
+
should "complain if writing a file source with a file that does not exist" do
|
54
|
+
assert_raises(ArgumentError) { subject.source = @does_not_exist_path }
|
55
|
+
end
|
56
|
+
|
57
|
+
should "set its data to the contents of the file when writing a file source" do
|
58
|
+
subject.source = @content_file
|
59
|
+
assert_equal @content_file_data, subject.data
|
60
|
+
end
|
31
61
|
|
32
|
-
should "
|
33
|
-
|
62
|
+
should "set its data to the proc when writing a proc source" do
|
63
|
+
subject.source = @hi_proc
|
64
|
+
assert_equal @hi_proc, subject.data
|
34
65
|
end
|
35
66
|
|
36
67
|
end
|
37
68
|
|
38
|
-
class
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
69
|
+
class LayoutWriterTests < BasicTests
|
70
|
+
|
71
|
+
should "write nil layout values" do
|
72
|
+
subject.layout = nil
|
73
|
+
assert_nil subject.layout
|
74
|
+
end
|
75
|
+
|
76
|
+
should "write source layouts given a source" do
|
77
|
+
subject.layout = @hi_proc_source
|
78
|
+
assert_equal @hi_proc_source, subject.layout
|
79
|
+
end
|
80
|
+
|
81
|
+
should "write proc source layouts given a proc" do
|
82
|
+
subject.layout = @hi_proc
|
83
|
+
assert_equal @hi_proc_source, subject.layout
|
84
|
+
end
|
85
|
+
|
86
|
+
should "write file source layouts given a file path" do
|
87
|
+
subject.layout = @content_file
|
88
|
+
assert_equal @content_file_source, subject.layout
|
89
|
+
end
|
90
|
+
|
91
|
+
should "write named source layouts given a named source" do
|
92
|
+
subject.layout = @named_source
|
93
|
+
assert_equal @named_source_source, subject.layout
|
94
|
+
end
|
95
|
+
|
96
|
+
should "complain if trying to write an invalid layout value" do
|
97
|
+
assert_raises(ArgumentError) { subject.layout = 345 }
|
98
|
+
assert_raises(ArgumentError) { subject.layout = true }
|
99
|
+
end
|
100
|
+
|
101
|
+
should "know its layouts, layout sources" do
|
102
|
+
assert_equal [], subject.layouts
|
103
|
+
assert_equal [], subject.layout_sources
|
104
|
+
|
105
|
+
subject.layout = (lay1 = Undies::Source.new(@content_file, {
|
106
|
+
:layout => (lay2 = Undies::Source.new(@content_file, {
|
107
|
+
:layout => (lay3 = Undies::Source.new(@content_file))
|
108
|
+
}))
|
109
|
+
}))
|
110
|
+
|
111
|
+
assert_equal [lay1, lay2, lay3], subject.layouts
|
112
|
+
assert_equal [@content_file, @content_file, @content_file], subject.layout_sources
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
class ArgsParserTests < BasicTests
|
118
|
+
|
119
|
+
should "parse block arg as proc source" do
|
120
|
+
s = Undies::Source.new(&@hi_proc)
|
121
|
+
assert_not s.file?
|
122
|
+
assert_equal @hi_proc, s.source
|
123
|
+
assert_equal @hi_proc, s.data
|
124
|
+
end
|
125
|
+
|
126
|
+
should "parse path arg as a file source" do
|
127
|
+
s = Undies::Source.new(@content_file)
|
128
|
+
assert s.file?
|
129
|
+
assert_equal @content_file, s.source
|
130
|
+
assert_equal @content_file_data, s.data
|
131
|
+
end
|
132
|
+
|
133
|
+
should "parse opts arg" do
|
134
|
+
opts = {:layout => @content_file_source}
|
135
|
+
assert_equal @content_file_source, Undies::Source.new(@content_file, opts).layout
|
136
|
+
assert_equal @content_file_source, Undies::Source.new(opts, &@hi_proc).layout
|
137
|
+
end
|
138
|
+
|
139
|
+
should "parse named source as named source args" do
|
140
|
+
s = Undies::Source.new(@named_source)
|
141
|
+
assert_equal @named_source_source, s
|
142
|
+
end
|
143
|
+
|
144
|
+
should "parse named source layouts" do
|
145
|
+
s = Undies::Source.new({:layout => @named_source}, &@hi_proc)
|
146
|
+
assert_equal @named_source_source, s.layout
|
43
147
|
end
|
44
148
|
|
45
|
-
should "
|
46
|
-
|
149
|
+
should "complain if building a source from an unknown named source" do
|
150
|
+
assert_raises(ArgumentError) { Undies::Source.new(:wtf) }
|
47
151
|
end
|
48
152
|
|
49
153
|
end
|