trenni 3.0.4 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +105 -0
- data/lib/trenni/uri.rb +85 -0
- data/lib/trenni/version.rb +1 -1
- data/spec/trenni/parsers_performance_spec.rb +54 -22
- data/spec/trenni/template_spec/large.erb +16 -0
- data/spec/trenni/uri_spec.rb +55 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ca1689a6184db9df2773f6d3b4b6211ed558f1a
|
4
|
+
data.tar.gz: 97d4dc5f0e2fa4f7f165519bc8f3c86c8e36c822
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c57c4f0c3463d35c0d73142be0451ea2243901fc67801d36f9dded3acc1118a85104be7138da3a442028e267333099772d2f867e6517ab0c6abb47acf731dc2a
|
7
|
+
data.tar.gz: 1b84a6d7d545ac7fc8de48c203f8d8cd1ab8652ce422f6c8da1e754d2d67023db807e96d2c236926ad34d88b4cf1f938c5a60ca498daf3a3f1c27b305f7d6ccc
|
data/README.md
CHANGED
@@ -172,6 +172,111 @@ To test the native C parsers:
|
|
172
172
|
|
173
173
|
rake generate_native_parsers && rake compile && rspec
|
174
174
|
|
175
|
+
### Benchmarks
|
176
|
+
|
177
|
+
Trenni has a pure Ruby implemenation, with performance critical operations implemented natively. All critical code paths have benchmark specs.
|
178
|
+
|
179
|
+
#### Parser Performance
|
180
|
+
|
181
|
+
You can evaluate and compare template performance with ERB:
|
182
|
+
|
183
|
+
```
|
184
|
+
rspec spec/trenni/parsers_performance_spec.rb
|
185
|
+
|
186
|
+
Trenni::Native
|
187
|
+
#parse_markup
|
188
|
+
Warming up --------------------------------------
|
189
|
+
Large (Trenni) 64.000 i/100ms
|
190
|
+
Large (Nokogiri) 30.000 i/100ms
|
191
|
+
Calculating -------------------------------------
|
192
|
+
Large (Trenni) 637.720 (± 6.4%) i/s - 3.200k in 5.038187s
|
193
|
+
Large (Nokogiri) 294.762 (± 5.8%) i/s - 1.470k in 5.004284s
|
194
|
+
|
195
|
+
Comparison:
|
196
|
+
Large (Trenni): 637.7 i/s
|
197
|
+
Large (Nokogiri): 294.8 i/s - 2.16x slower
|
198
|
+
|
199
|
+
should be fast to parse large documents
|
200
|
+
#parse_template
|
201
|
+
Warming up --------------------------------------
|
202
|
+
Large (Trenni) 7.791k i/100ms
|
203
|
+
Large (ERB) 488.000 i/100ms
|
204
|
+
Calculating -------------------------------------
|
205
|
+
Large (Trenni) 87.889k (± 9.5%) i/s - 436.296k in 5.024283s
|
206
|
+
Large (ERB) 4.844k (± 5.6%) i/s - 24.400k in 5.053247s
|
207
|
+
|
208
|
+
Comparison:
|
209
|
+
Large (Trenni): 87889.4 i/s
|
210
|
+
Large (ERB): 4844.5 i/s - 18.14x slower
|
211
|
+
|
212
|
+
should have better performance using instance
|
213
|
+
|
214
|
+
Finished in 28.2 seconds (files took 0.14204 seconds to load)
|
215
|
+
2 examples, 0 failures
|
216
|
+
```
|
217
|
+
|
218
|
+
To run this with the pure ruby implementation, use `TRENNI_PREFER_FALLBACK=y rspec spec/trenni/parsers_performance_spec.rb`.
|
219
|
+
|
220
|
+
#### Markup String Performance
|
221
|
+
|
222
|
+
Markup safe strings require escaping characters. Doing this natively makes sense, and in MRI, `CGI.escape_html` is implemented in C. Strings that include characters that need to be escaped are a bit slower because a new string must be allocated and modified. So, we test these two cases.
|
223
|
+
|
224
|
+
```
|
225
|
+
rspec spec/trenni/markup_performance_spec.rb
|
226
|
+
|
227
|
+
Trenni::Markup
|
228
|
+
Warming up --------------------------------------
|
229
|
+
General String 179.396k i/100ms
|
230
|
+
Code String 85.050k i/100ms
|
231
|
+
Calculating -------------------------------------
|
232
|
+
General String 4.773M (±10.0%) i/s - 23.680M in 5.027576s
|
233
|
+
Code String 1.469M (± 5.7%) i/s - 7.399M in 5.052467s
|
234
|
+
|
235
|
+
Comparison:
|
236
|
+
General String: 4773201.3 i/s
|
237
|
+
Code String: 1469345.5 i/s - 3.25x slower
|
238
|
+
|
239
|
+
should be fast to parse large documents
|
240
|
+
|
241
|
+
Finished in 14.11 seconds (files took 0.09696 seconds to load)
|
242
|
+
1 example, 0 failures
|
243
|
+
```
|
244
|
+
|
245
|
+
#### Template Evaluation Performance
|
246
|
+
|
247
|
+
Evaluating templates and generating output is critical to performance. You can compare Trenni with ERB. The primary factor affecting performance, is the number of interpolations, because each interpolation requires evaluation and concatenation.
|
248
|
+
|
249
|
+
```
|
250
|
+
rspec spec/trenni/template_performance_spec.rb
|
251
|
+
|
252
|
+
Trenni::Template
|
253
|
+
Warming up --------------------------------------
|
254
|
+
Trenni 79.000 i/100ms
|
255
|
+
Calculating -------------------------------------
|
256
|
+
Trenni 817.703 (± 7.7%) i/s - 4.108k in 5.071586s
|
257
|
+
should be fast for lots of interpolations
|
258
|
+
Warming up --------------------------------------
|
259
|
+
Trenni (object) 79.149k i/100ms
|
260
|
+
ERB (binding) 5.416k i/100ms
|
261
|
+
Calculating -------------------------------------
|
262
|
+
Trenni (object) 1.081M (± 3.7%) i/s - 5.461M in 5.059151s
|
263
|
+
ERB (binding) 59.016k (± 4.7%) i/s - 297.880k in 5.058614s
|
264
|
+
|
265
|
+
Comparison:
|
266
|
+
Trenni (object): 1080909.2 i/s
|
267
|
+
ERB (binding): 59016.3 i/s - 18.32x slower
|
268
|
+
|
269
|
+
should be fast for basic templates
|
270
|
+
Warming up --------------------------------------
|
271
|
+
Trenni 34.204k i/100ms
|
272
|
+
Calculating -------------------------------------
|
273
|
+
Trenni 407.905k (± 9.0%) i/s - 2.018M in 5.001248s
|
274
|
+
should be fast with capture
|
275
|
+
|
276
|
+
Finished in 28.25 seconds (files took 0.09765 seconds to load)
|
277
|
+
3 examples, 0 failures
|
278
|
+
```
|
279
|
+
|
175
280
|
## Contributing
|
176
281
|
|
177
282
|
1. Fork it
|
data/lib/trenni/uri.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Trenni
|
22
|
+
class URI
|
23
|
+
def initialize(base, fragment, query)
|
24
|
+
@base = base
|
25
|
+
@fragment = fragment
|
26
|
+
@query = query
|
27
|
+
end
|
28
|
+
|
29
|
+
attr :base
|
30
|
+
attr :fragment
|
31
|
+
attr :query
|
32
|
+
|
33
|
+
def append(buffer)
|
34
|
+
buffer << escape_path(@base)
|
35
|
+
|
36
|
+
if @query&.any?
|
37
|
+
buffer << query_separator << query_part
|
38
|
+
end
|
39
|
+
|
40
|
+
if @fragment
|
41
|
+
buffer << '#' << escape(@fragment)
|
42
|
+
end
|
43
|
+
|
44
|
+
return buffer
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_str
|
48
|
+
append(String.new)
|
49
|
+
end
|
50
|
+
|
51
|
+
alias to_s to_str
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Escapes a path string, using percent encoding, but additionally ignoring "/" and substituting spaces with "+".
|
56
|
+
def escape_path(path)
|
57
|
+
encoding = path.encoding
|
58
|
+
path.b.gsub(/([^ a-zA-Z0-9_.\-\/:]+)/) do |m|
|
59
|
+
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
|
60
|
+
end.tr(' ', '+').force_encoding(encoding)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Escapes a generic string, using percent encoding.
|
64
|
+
def escape(string)
|
65
|
+
encoding = string.encoding
|
66
|
+
string.b.gsub(/([^a-zA-Z0-9_.\-]+)/) do |m|
|
67
|
+
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
|
68
|
+
end.force_encoding(encoding)
|
69
|
+
end
|
70
|
+
|
71
|
+
def query_part
|
72
|
+
@query.map{|k,v| "#{escape(k.to_s)}=#{escape(v.to_s)}"}.join('&')
|
73
|
+
end
|
74
|
+
|
75
|
+
def query_separator
|
76
|
+
@base.include?('?') ? '&' : '?'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.URI(path = '', query = nil)
|
81
|
+
base, fragment = path.split('#', 2)
|
82
|
+
|
83
|
+
URI.new(base, fragment, query)
|
84
|
+
end
|
85
|
+
end
|
data/lib/trenni/version.rb
CHANGED
@@ -8,34 +8,66 @@ require 'nokogiri'
|
|
8
8
|
RSpec.describe Trenni::Parsers do
|
9
9
|
# include_context "profile"
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
describe '#parse_markup' do
|
12
|
+
let(:xhtml_path) {File.expand_path('corpus/large.xhtml', __dir__)}
|
13
|
+
let(:xhtml_buffer) {Trenni::FileBuffer.new(xhtml_path)}
|
14
|
+
let(:entities) {Trenni::Entities::HTML5}
|
15
|
+
|
16
|
+
it "should be fast to parse large documents" do
|
17
|
+
Benchmark.ips do |x|
|
18
|
+
x.report("Large (Trenni)") do |times|
|
19
|
+
delegate = Trenni::ParseDelegate.new
|
20
|
+
|
21
|
+
while (times -= 1) >= 0
|
22
|
+
Trenni::Parsers.parse_markup(xhtml_buffer, delegate, entities)
|
23
|
+
|
24
|
+
delegate.events.clear
|
25
|
+
end
|
26
|
+
end
|
19
27
|
|
20
|
-
|
21
|
-
Trenni::
|
28
|
+
x.report("Large (Nokogiri)") do |times|
|
29
|
+
delegate = Trenni::ParseDelegate.new
|
30
|
+
parser = Nokogiri::HTML::SAX::Parser.new(delegate)
|
22
31
|
|
23
|
-
|
32
|
+
while (times -= 1) >= 0
|
33
|
+
parser.parse(xhtml_buffer.read)
|
34
|
+
|
35
|
+
delegate.events.clear
|
36
|
+
end
|
24
37
|
end
|
25
|
-
end
|
26
|
-
|
27
|
-
x.report("Large (Nokogiri)") do |times|
|
28
|
-
delegate = Trenni::ParseDelegate.new
|
29
|
-
parser = Nokogiri::HTML::SAX::Parser.new(delegate)
|
30
38
|
|
31
|
-
|
32
|
-
|
39
|
+
x.compare!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#parse_template' do
|
45
|
+
let(:large_trenni_path) {File.expand_path('template_spec/large.trenni', __dir__)}
|
46
|
+
let(:trenni_buffer) {Trenni::FileBuffer.new(large_trenni_path)}
|
47
|
+
|
48
|
+
let(:large_erb_path) {File.expand_path('template_spec/large.erb', __dir__)}
|
49
|
+
let(:erb_buffer) {Trenni::FileBuffer.new(large_erb_path)}
|
50
|
+
|
51
|
+
it "should be fast to parse large templates" do
|
52
|
+
Benchmark.ips do |x|
|
53
|
+
x.report("Large (Trenni)") do |times|
|
54
|
+
delegate = Trenni::ParseDelegate.new
|
33
55
|
|
34
|
-
|
56
|
+
while (times -= 1) >= 0
|
57
|
+
Trenni::Parsers.parse_template(trenni_buffer, delegate)
|
58
|
+
|
59
|
+
delegate.events.clear
|
60
|
+
end
|
35
61
|
end
|
62
|
+
|
63
|
+
x.report("Large (ERB)") do |times|
|
64
|
+
while (times -= 1) >= 0
|
65
|
+
ERB.new(erb_buffer.read)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
x.compare!
|
36
70
|
end
|
37
|
-
|
38
|
-
x.compare!
|
39
71
|
end
|
40
72
|
end
|
41
|
-
end
|
73
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent gravida, turpis id bibendum bibendum, ipsum diam vestibulum arcu, sit amet tempor ipsum lorem non urna. Suspendisse nec nisl a risus laoreet lacinia ac sit amet neque. Mauris vel turpis semper massa bibendum viverra. Curabitur vel felis est. Donec sed faucibus augue, ac molestie purus. Nulla a lectus dui. Quisque id scelerisque urna. Aenean in vehicula nibh, in aliquam turpis. <%='Suspendisse'%> iaculis suscipit lectus in efficitur. Nulla facilisi. Fusce facilisis, justo ac eleifend convallis, ligula est bibendum risus, a consequat metus sapien eget mauris. Sed quis mollis tellus, sed tempor lacus. Proin et efficitur metus. Vestibulum blandit tellus sed turpis tincidunt, in aliquet augue bibendum. Suspendisse venenatis faucibus lectus sed convallis.
|
2
|
+
|
3
|
+
<%='Curabitur'%> aliquet ligula et volutpat efficitur. Duis sed tortor elit. Quisque justo eros, maximus quis elit sed, accumsan faucibus lectus. Nulla blandit quam urna, ac bibendum turpis semper quis. Proin a ligula eu eros semper condimentum. Ut pellentesque, justo sed malesuada condimentum, est massa tempor turpis, id facilisis neque odio eu neque. Morbi convallis laoreet tortor, ut dapibus mi accumsan a. Proin convallis neque sed leo blandit lacinia. Phasellus porta odio nunc, quis placerat sem facilisis quis. Quisque et <%='ornare'%> elit. Duis efficitur cursus lectus vitae placerat. In lacinia eros nec feugiat finibus.
|
4
|
+
|
5
|
+
Morbi orci magna, tempor at convallis sed, porta elementum nulla. Aliquam sit amet fringilla felis, eget volutpat lorem. Pellentesque laoreet, elit quis fringilla ultricies, leo nisl semper mauris, ac feugiat libero tortor id urna. Praesent ligula augue, mollis nec justo vitae, faucibus posuere risus. Praesent blandit molestie ex eu fringilla. Ut non vehicula mauris. Aliquam gravida rutrum laoreet. Pellentesque facilisis mi ipsum, ac dapibus mi iaculis nec.
|
6
|
+
|
7
|
+
Vestibulum sit amet nibh velit. Sed rhoncus odio ut nisi blandit vestibulum. Aliquam erat volutpat. Suspendisse sed posuere ligula. Proin ex ex, pharetra vel dui vulputate, pellentesque ullamcorper metus. Cras imperdiet dictum lorem. Nullam eleifend nunc eu metus ullamcorper dignissim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sit amet sem sed enim rutrum volutpat a non libero.
|
8
|
+
|
9
|
+
<% 10.downto(1) do |i| -%>
|
10
|
+
<%=i%> bottle<%=i == 1 ? '' : 's'%> of beer on the wall,
|
11
|
+
<%=i%> bottle<%=i == 1 ? '' : 's'%> of beer,
|
12
|
+
Take one down and pass it around,
|
13
|
+
<%=i-1%> bottle<%=i == 1 ? '' : 's'%> of beer on the wall.
|
14
|
+
<% end -%>
|
15
|
+
|
16
|
+
Integer in ligula at ex gravida pellentesque in et felis. Nulla dolor sapien, pretium a odio a, consectetur ultrices justo. Suspendisse libero quam, pulvinar eu est non, fermentum volutpat nisl. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras at dapibus lorem, nec imperdiet quam. Proin ut tellus sagittis, sollicitudin elit ac, porttitor diam. Quisque at hendrerit lacus, sit amet mollis lacus.
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'trenni/uri'
|
24
|
+
|
25
|
+
RSpec.describe Trenni::URI do
|
26
|
+
describe Trenni::URI('path with spaces/image.jpg') do
|
27
|
+
it "encodes whitespace" do
|
28
|
+
expect(subject.to_s).to be == "path+with+spaces/image.jpg"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe Trenni::URI('index', 'my name' => 'Bob Dole') do
|
33
|
+
it "encodes query" do
|
34
|
+
expect(subject.to_s).to be == "index?my%20name=Bob%20Dole"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe Trenni::URI('index#All Your Base') do
|
39
|
+
it "encodes fragment" do
|
40
|
+
expect(subject.to_s).to be == "index\#All%20Your%20Base"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe Trenni::URI('I/❤️/UNICODE', face: '😀') do
|
45
|
+
it "encodes unicode" do
|
46
|
+
expect(subject.to_s).to be == "I/%E2%9D%A4%EF%B8%8F/UNICODE?face=%F0%9F%98%80"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can be an attribute" do
|
51
|
+
tag = Trenni::Tag.closed('img', src: Trenni::URI('image.jpg', x: 10))
|
52
|
+
|
53
|
+
expect(tag.to_s).to be == '<img src="image.jpg?x=10"/>'
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trenni
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- lib/trenni/strings.rb
|
120
120
|
- lib/trenni/tag.rb
|
121
121
|
- lib/trenni/template.rb
|
122
|
+
- lib/trenni/uri.rb
|
122
123
|
- lib/trenni/version.rb
|
123
124
|
- parsers/trenni/entities.rl
|
124
125
|
- parsers/trenni/markup.rl
|
@@ -142,9 +143,11 @@ files:
|
|
142
143
|
- spec/trenni/template_spec/error.trenni
|
143
144
|
- spec/trenni/template_spec/escaped.trenni
|
144
145
|
- spec/trenni/template_spec/interpolations.trenni
|
146
|
+
- spec/trenni/template_spec/large.erb
|
145
147
|
- spec/trenni/template_spec/large.trenni
|
146
148
|
- spec/trenni/template_spec/lines.trenni
|
147
149
|
- spec/trenni/template_spec/nested.trenni
|
150
|
+
- spec/trenni/uri_spec.rb
|
148
151
|
- tasks/entities.rake
|
149
152
|
- tasks/parsers.rake
|
150
153
|
- trenni.gemspec
|
@@ -191,6 +194,8 @@ test_files:
|
|
191
194
|
- spec/trenni/template_spec/error.trenni
|
192
195
|
- spec/trenni/template_spec/escaped.trenni
|
193
196
|
- spec/trenni/template_spec/interpolations.trenni
|
197
|
+
- spec/trenni/template_spec/large.erb
|
194
198
|
- spec/trenni/template_spec/large.trenni
|
195
199
|
- spec/trenni/template_spec/lines.trenni
|
196
200
|
- spec/trenni/template_spec/nested.trenni
|
201
|
+
- spec/trenni/uri_spec.rb
|