cutaneous 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Gemfile +3 -0
  2. data/LICENSE +0 -0
  3. data/README.md +0 -0
  4. data/Rakefile +150 -0
  5. data/cutaneous.gemspec +103 -0
  6. data/lib/cutaneous/compiler/expression.rb +85 -0
  7. data/lib/cutaneous/compiler.rb +223 -0
  8. data/lib/cutaneous/context.rb +70 -0
  9. data/lib/cutaneous/engine.rb +66 -0
  10. data/lib/cutaneous/lexer.rb +92 -0
  11. data/lib/cutaneous/loader.rb +147 -0
  12. data/lib/cutaneous/syntax.rb +39 -0
  13. data/lib/cutaneous/template.rb +40 -0
  14. data/lib/cutaneous.rb +23 -0
  15. data/test/fixtures/a.html.cut +13 -0
  16. data/test/fixtures/b.html.cut +8 -0
  17. data/test/fixtures/c.html.cut +8 -0
  18. data/test/fixtures/comments.html.cut +1 -0
  19. data/test/fixtures/d.html.cut +8 -0
  20. data/test/fixtures/e.html.cut +4 -0
  21. data/test/fixtures/error.html.cut +30 -0
  22. data/test/fixtures/expressions.html.cut +1 -0
  23. data/test/fixtures/include.html.cut +3 -0
  24. data/test/fixtures/include.rss.cut +3 -0
  25. data/test/fixtures/included_error.html.cut +1 -0
  26. data/test/fixtures/instance.html.cut +2 -0
  27. data/test/fixtures/instance_include.html.cut +1 -0
  28. data/test/fixtures/missing.html.cut +1 -0
  29. data/test/fixtures/other/different.html.cut +1 -0
  30. data/test/fixtures/other/error.html.cut +5 -0
  31. data/test/fixtures/partial.html.cut +1 -0
  32. data/test/fixtures/partial.rss.cut +1 -0
  33. data/test/fixtures/render.html.cut +6 -0
  34. data/test/fixtures/statements.html.cut +3 -0
  35. data/test/fixtures/target.html.cut +1 -0
  36. data/test/fixtures/whitespace.html.cut +6 -0
  37. data/test/helper.rb +18 -0
  38. data/test/test_blocks.rb +19 -0
  39. data/test/test_cache.rb +104 -0
  40. data/test/test_core.rb +168 -0
  41. metadata +90 -0
data/test/test_core.rb ADDED
@@ -0,0 +1,168 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ describe Cutaneous do
4
+ let(:template_root) { File.expand_path("../fixtures", __FILE__) }
5
+ let(:engine) { Cutaneous::Engine.new(template_root, Cutaneous::FirstPassSyntax, "html") }
6
+
7
+ it "Will parse & execute a simple template with expressions" do
8
+ context = ContextHash(right: "right", code: "<tag/>")
9
+ result = engine.render("expressions", context)
10
+ result.must_equal "This is right &lt;tag/&gt;\n"
11
+ end
12
+
13
+ it "Will parse & execute a simple template with statements" do
14
+ context = ContextHash(right: "right")
15
+ result = engine.render("statements", context)
16
+ result.must_equal "\nThis is right 0\n\nThis is right 1\n\nThis is right 2\n\n"
17
+ end
18
+
19
+ it "Will parse & execute a simple template with comments" do
20
+ context = ContextHash(right: "right")
21
+ result = engine.render("comments", context)
22
+ result.must_equal "\n"
23
+ end
24
+
25
+ it "Will remove whitespace after tags with a closing '-'" do
26
+ context = ContextHash(right: "right")
27
+ result = engine.render("whitespace", context)
28
+ expected = ["aa", "here 0", "here 1", "here 2\n", "ac\n", "ad\n", "ae\n", "af\n", "ag\n"].join("\n")
29
+ result.must_equal expected
30
+ end
31
+
32
+ it "Allows you to include other templates and pass them parameters" do
33
+ context = ContextHash(right: "right")
34
+ result = engine.render("include", context)
35
+ result.must_equal "right = right\nright = wrong\nright = left\n"
36
+ end
37
+
38
+ it "Honors the format parameter" do
39
+ context = ContextHash(right: "right")
40
+ result = engine.render("include", context, "rss")
41
+ result.must_equal "right = rss\nwrong = rss\nleft = rss\n"
42
+ end
43
+
44
+ it "Passes instance variables onto includes" do
45
+ context = ContextHash(right: "right")
46
+ result = engine.render("instance", context)
47
+ result.must_equal "left = wrong\n"
48
+ end
49
+
50
+ it "Allows you to render a template string" do
51
+ context = ContextHash(right: "left")
52
+ result = engine.render_string("${ right }", context)
53
+ result.must_equal "left"
54
+ end
55
+
56
+ it "Lets you mix template tags" do
57
+ context = ContextHash(right: "left")
58
+ result = engine.render_string("${ right } = {{ result }}", context)
59
+ result.must_equal "left = {{ result }}"
60
+ end
61
+
62
+ it "Has a configurable lexer class" do
63
+ engine = Cutaneous::Engine.new(template_root, Cutaneous::SecondPassSyntax)
64
+ context = ContextHash(right: "wrong")
65
+ result = engine.render_string("${ left } = {{ right }}", context)
66
+ result.must_equal "${ left } = wrong"
67
+ end
68
+
69
+ it "Allows for multiple template roots" do
70
+ roots = Array(template_root)
71
+ roots.push File.join(template_root, "other")
72
+ engine = Cutaneous::Engine.new(roots, Cutaneous::FirstPassSyntax)
73
+ context = ContextHash(right: "wrong")
74
+ result = engine.render_string('%{ include "different" }', context)
75
+ result.must_equal "wrong\n"
76
+ end
77
+
78
+ it "Throws a resonable error if asked to include a non-existant file" do
79
+ context = ContextHash(right: "wrong")
80
+ test = proc { engine.render_string('%{ include "different" }', context) }
81
+ test.must_raise Cutaneous::UnknownTemplateError
82
+ end
83
+
84
+ it "Maintains source line numbers for exceptions" do
85
+ context = ContextHash(right: "wrong")
86
+ test = proc { engine.render("error", context) }
87
+ test.must_raise RuntimeError
88
+ backtrace = message = nil
89
+ begin
90
+ test.call
91
+ rescue RuntimeError => e
92
+ message = e.message
93
+ backtrace = e.backtrace
94
+ end
95
+ filename, line = backtrace.first.split(":")
96
+ filename.must_equal File.join(template_root, "error.html.cut")
97
+ line.must_equal message
98
+ end
99
+
100
+ it "Maintains source line numbers for exceptions raised by includes" do
101
+ context = ContextHash(right: "wrong")
102
+ test = proc { engine.render("included_error", context) }
103
+ test.must_raise RuntimeError
104
+ backtrace = message = nil
105
+ begin
106
+ test.call
107
+ rescue RuntimeError => e
108
+ message = e.message
109
+ backtrace = e.backtrace
110
+ end
111
+ filename, line = backtrace.first.split(":")
112
+ filename.must_equal File.join(template_root, "other/error.html.cut")
113
+ line.must_equal message
114
+ end
115
+
116
+ it "Renders proc instances as strings" do
117
+ context = ContextHash(right: "wrong")
118
+ template = proc { "right" }
119
+ result = engine.render(template, context, "rss")
120
+ result.must_equal "right"
121
+ end
122
+
123
+ it "Allows for configuration of the engine's default format" do
124
+ engine.default_format = "rss"
125
+ context = ContextHash(right: "right")
126
+ result = engine.render("include", context)
127
+ result.must_equal "right = rss\nwrong = rss\nleft = rss\n"
128
+ end
129
+
130
+ it "Accepts absolute template paths" do
131
+ context = ContextHash(right: "right", code: "<tag/>")
132
+ result = engine.render(File.join(template_root, "expressions"), context)
133
+ result.must_equal "This is right &lt;tag/&gt;\n"
134
+ end
135
+
136
+ it "Tests for the existence of a template file for a certain format" do
137
+ assert engine.template_exists?(template_root, "expressions", "html")
138
+ assert engine.template_exists?(template_root, "other/error", "html")
139
+ assert engine.template_exists?(template_root, "include", "rss")
140
+ refute engine.template_exists?(template_root, "missing", "rss")
141
+ end
142
+
143
+ it "Passes any instance variables & locals between contexts" do
144
+ context = ContextHash(right: "left")
145
+ result1 = engine.render("instance", context)
146
+ context = ContextHash(context)
147
+ result2 = engine.render("instance", context)
148
+ result2.must_equal result1
149
+ end
150
+
151
+ it "Silently discards missing variables" do
152
+ context = ContextHash(right: "left")
153
+ result1 = engine.render("missing", context)
154
+ result1.must_equal "missing: \n"
155
+ end
156
+
157
+ it "Overwrites object methods with parameters" do
158
+ klass = Class.new(Object) do
159
+ def monkey; "see"; end
160
+ end
161
+ context = TestContext.new(klass.new)
162
+ result = engine.render_string("${ monkey }", context)
163
+ result.must_equal "see"
164
+ context = TestContext.new(klass.new, monkey: "magic")
165
+ result = engine.render_string("${ monkey }", context)
166
+ result.must_equal "magic"
167
+ end
168
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cutaneous
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Garry Hill
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-23 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Long description. Maybe copied from the README.
15
+ email: garry@spontaneous.io
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - README.md
20
+ - LICENSE
21
+ files:
22
+ - Gemfile
23
+ - LICENSE
24
+ - README.md
25
+ - Rakefile
26
+ - cutaneous.gemspec
27
+ - lib/cutaneous.rb
28
+ - lib/cutaneous/compiler.rb
29
+ - lib/cutaneous/compiler/expression.rb
30
+ - lib/cutaneous/context.rb
31
+ - lib/cutaneous/engine.rb
32
+ - lib/cutaneous/lexer.rb
33
+ - lib/cutaneous/loader.rb
34
+ - lib/cutaneous/syntax.rb
35
+ - lib/cutaneous/template.rb
36
+ - test/fixtures/a.html.cut
37
+ - test/fixtures/b.html.cut
38
+ - test/fixtures/c.html.cut
39
+ - test/fixtures/comments.html.cut
40
+ - test/fixtures/d.html.cut
41
+ - test/fixtures/e.html.cut
42
+ - test/fixtures/error.html.cut
43
+ - test/fixtures/expressions.html.cut
44
+ - test/fixtures/include.html.cut
45
+ - test/fixtures/include.rss.cut
46
+ - test/fixtures/included_error.html.cut
47
+ - test/fixtures/instance.html.cut
48
+ - test/fixtures/instance_include.html.cut
49
+ - test/fixtures/missing.html.cut
50
+ - test/fixtures/other/different.html.cut
51
+ - test/fixtures/other/error.html.cut
52
+ - test/fixtures/partial.html.cut
53
+ - test/fixtures/partial.rss.cut
54
+ - test/fixtures/render.html.cut
55
+ - test/fixtures/statements.html.cut
56
+ - test/fixtures/target.html.cut
57
+ - test/fixtures/whitespace.html.cut
58
+ - test/helper.rb
59
+ - test/test_blocks.rb
60
+ - test/test_cache.rb
61
+ - test/test_core.rb
62
+ homepage: https://github.com/SpontaneousCMS/cutaneous
63
+ licenses: []
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project: cutaneous
83
+ rubygems_version: 1.8.21
84
+ signing_key:
85
+ specification_version: 2
86
+ summary: Short description used in Gem listings.
87
+ test_files:
88
+ - test/test_blocks.rb
89
+ - test/test_cache.rb
90
+ - test/test_core.rb