curly-templates 0.10.2 → 0.11.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ### Unreleased
2
2
 
3
+ ### Curly 0.11.0 (July 31, 2013)
4
+
5
+ * Make Curly raise an exception when a reference or comment is not closed.
6
+
7
+ *Daniel Schierbeck*
8
+
9
+ * Fix a bug that caused an infinite loop when there was whitespace in a reference.
10
+
11
+ *Daniel Schierbeck*
12
+
3
13
  ### Curly 0.10.2 (July 11, 2013)
4
14
 
5
15
  * Fix a bug that caused non-string presenter method return values to be
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'curly-templates'
7
- s.version = '0.10.2'
8
- s.date = '2013-07-11'
7
+ s.version = '0.11.0'
8
+ s.date = '2013-07-31'
9
9
 
10
10
  s.summary = "Free your views!"
11
11
  s.description = "A view layer for your Rails apps that separates structure and logic."
@@ -42,6 +42,7 @@ Gem::Specification.new do |s|
42
42
  lib/curly/presenter.rb
43
43
  lib/curly/railtie.rb
44
44
  lib/curly/scanner.rb
45
+ lib/curly/syntax_error.rb
45
46
  lib/curly/template_handler.rb
46
47
  lib/generators/curly/controller/controller_generator.rb
47
48
  lib/generators/curly/controller/templates/presenter.rb.erb
@@ -52,6 +53,7 @@ Gem::Specification.new do |s|
52
53
  spec/presenter_spec.rb
53
54
  spec/scanner_spec.rb
54
55
  spec/spec_helper.rb
56
+ spec/syntax_error_spec.rb
55
57
  spec/template_handler_spec.rb
56
58
  ]
57
59
  # = MANIFEST =
data/lib/curly.rb CHANGED
@@ -26,7 +26,7 @@
26
26
  # See Curly::Presenter for more information on presenters.
27
27
  #
28
28
  module Curly
29
- VERSION = "0.10.2"
29
+ VERSION = "0.11.0"
30
30
 
31
31
  # Compiles a Curly template to Ruby code.
32
32
  #
@@ -85,10 +85,6 @@ module Curly
85
85
  'buffer.safe_concat(%s)' % text.inspect
86
86
  end
87
87
 
88
- def compile_comment_line(comment)
89
- "" # Replace the content with an empty string.
90
- end
91
-
92
88
  def compile_comment(comment)
93
89
  "" # Replace the content with an empty string.
94
90
  end
data/lib/curly/scanner.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'strscan'
2
+ require 'curly/syntax_error'
2
3
 
3
4
  module Curly
4
5
 
@@ -8,9 +9,9 @@ module Curly
8
9
  # until the end of the template is reached.
9
10
  #
10
11
  class Scanner
11
- REFERENCE_REGEX = %r(\{\{[\w\.]+\}\})
12
- COMMENT_REGEX = %r(\{\{!.*\}\})
13
- COMMENT_LINE_REGEX = %r(\s*#{COMMENT_REGEX}\s*\n)
12
+ CURLY_START = /\{\{/
13
+ CURLY_END = /\}\}/
14
+ COMMENT_MARKER = /!/
14
15
 
15
16
  # Scans a Curly template for tokens.
16
17
  #
@@ -44,58 +45,41 @@ module Curly
44
45
  # Returns a two-element Array, the first element being the Symbol type of
45
46
  # the token and the second being the String value.
46
47
  def scan_token
47
- scan_reference ||
48
- scan_comment_line ||
49
- scan_comment ||
50
- scan_text ||
51
- scan_remainder
48
+ scan_curly || scan_text
52
49
  end
53
50
 
54
- # Scans a reference token, if a reference is the next token in the template.
55
- #
56
- # Returns an Array representing the token, or nil if no reference token can
57
- # be found at the current position.
58
- def scan_reference
59
- if value = @scanner.scan(REFERENCE_REGEX)
60
- # Return the reference name excluding "{{" and "}}".
61
- [:reference, value[2..-3]]
51
+ def scan_curly
52
+ if @scanner.scan(CURLY_START)
53
+ scan_reference_or_comment or syntax_error!
62
54
  end
63
55
  end
64
56
 
65
- # Scans a comment line token, if a comment line is the next token in the
66
- # template.
67
- #
68
- # Returns an Array representing the token, or nil if no comment line token
69
- # can be found at the current position.
70
- def scan_comment_line
71
- if value = @scanner.scan(COMMENT_LINE_REGEX)
72
- # Returns the comment excluding "{{!" and "}}".
73
- [:comment_line, value[3..-4]]
57
+ def scan_reference_or_comment
58
+ if @scanner.scan(COMMENT_MARKER)
59
+ scan_comment
60
+ else
61
+ scan_reference
74
62
  end
75
63
  end
76
64
 
77
- # Scans a comment token, if a comment is the next token in the template.
78
- #
79
- # Returns an Array representing the token, or nil if no comment token can
80
- # be found at the current position.
81
65
  def scan_comment
82
- if value = @scanner.scan(COMMENT_REGEX)
83
- # Returns the comment excluding "{{!" and "}}".
84
- [:comment, value[3..-3]]
66
+ if value = scan_until_end_of_curly
67
+ [:comment, value]
68
+ end
69
+ end
70
+
71
+ def scan_reference
72
+ if value = scan_until_end_of_curly
73
+ [:reference, value]
85
74
  end
86
75
  end
87
76
 
88
- # Scans a text token, if a text is the next token in the template.
89
- #
90
- # Returns an Array representing the token, or nil if no text token can
91
- # be found at the current position.
92
77
  def scan_text
93
- if value = @scanner.scan_until(/\{\{/)
94
- # Rewind the scanner until before the "{{"
78
+ if value = scan_until_start_of_curly
95
79
  @scanner.pos -= 2
96
-
97
- # Return the text up until "{{".
98
- [:text, value[0..-3]]
80
+ [:text, value]
81
+ else
82
+ scan_remainder
99
83
  end
100
84
  end
101
85
 
@@ -107,5 +91,21 @@ module Curly
107
91
  [:text, value]
108
92
  end
109
93
  end
94
+
95
+ def scan_until_start_of_curly
96
+ if value = @scanner.scan_until(CURLY_START)
97
+ value[0..-3]
98
+ end
99
+ end
100
+
101
+ def scan_until_end_of_curly
102
+ if value = @scanner.scan_until(CURLY_END)
103
+ value[0..-3]
104
+ end
105
+ end
106
+
107
+ def syntax_error!
108
+ raise SyntaxError.new(@scanner.pos, @scanner.string)
109
+ end
110
110
  end
111
111
  end
@@ -0,0 +1,14 @@
1
+ module Curly
2
+ class SyntaxError < StandardError
3
+ def initialize(position, source)
4
+ @position, @source = position, source
5
+ end
6
+
7
+ def message
8
+ start = [@position - 8, 0].max
9
+ stop = [@position + 8, @source.length].min
10
+ snippet = @source[start..stop].strip
11
+ "invalid syntax near `#{snippet}` in template:\n\n#{@source}\n"
12
+ end
13
+ end
14
+ end
@@ -108,14 +108,6 @@ describe Curly::Compiler do
108
108
  evaluate("HELO{{! I'm a comment, yo }}WORLD").should == "HELOWORLD"
109
109
  end
110
110
 
111
- it "removes comment lines from the output" do
112
- evaluate(<<-CURLY.strip_heredoc).should == "HELO\nWORLD\n"
113
- HELO
114
- {{! I'm a comment }}
115
- WORLD
116
- CURLY
117
- end
118
-
119
111
  it "does not execute arbitrary Ruby code" do
120
112
  evaluate('#{foo}').should == '#{foo}'
121
113
  end
data/spec/scanner_spec.rb CHANGED
@@ -15,6 +15,12 @@ describe Curly::Scanner, ".scan" do
15
15
  ]
16
16
  end
17
17
 
18
+ it "allows references with whitespace" do
19
+ scan("{{ foo bar}}").should == [
20
+ [:reference, " foo bar"]
21
+ ]
22
+ end
23
+
18
24
  it "scans comments in the source" do
19
25
  scan("foo {{!bar}} baz").should == [
20
26
  [:text, "foo "],
@@ -23,11 +29,9 @@ describe Curly::Scanner, ".scan" do
23
29
  ]
24
30
  end
25
31
 
26
- it "scans comment lines in the source" do
27
- scan("foo\n{{!bar}}\nbaz").should == [
28
- [:text, "foo\n"],
29
- [:comment_line, "bar"],
30
- [:text, "baz"]
32
+ it "allows newlines in comments" do
33
+ scan("{{!\nfoo\n}}").should == [
34
+ [:comment, "\nfoo\n"]
31
35
  ]
32
36
  end
33
37
 
@@ -49,6 +53,18 @@ describe Curly::Scanner, ".scan" do
49
53
  ]
50
54
  end
51
55
 
56
+ it "raises Curly::SyntaxError on unclosed references" do
57
+ ["{{", "{{yolo"].each do |template|
58
+ expect { scan(template) }.to raise_error(Curly::SyntaxError)
59
+ end
60
+ end
61
+
62
+ it "raises Curly::SyntaxError on unclosed comments" do
63
+ ["{{!", "{{! foo bar"].each do |template|
64
+ expect { scan(template) }.to raise_error(Curly::SyntaxError)
65
+ end
66
+ end
67
+
52
68
  def scan(source)
53
69
  Curly::Scanner.scan(source)
54
70
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Curly::SyntaxError, "#message" do
4
+ it "includes the context of the error in the message" do
5
+ source = "I am a very bad error that has snuck in"
6
+ error = Curly::SyntaxError.new(13, source)
7
+
8
+ error.message.should == <<-MESSAGE.strip_heredoc
9
+ invalid syntax near `a very bad error` in template:
10
+
11
+ I am a very bad error that has snuck in
12
+ MESSAGE
13
+ end
14
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curly-templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.11.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-11 00:00:00.000000000 Z
12
+ date: 2013-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -123,6 +123,7 @@ files:
123
123
  - lib/curly/presenter.rb
124
124
  - lib/curly/railtie.rb
125
125
  - lib/curly/scanner.rb
126
+ - lib/curly/syntax_error.rb
126
127
  - lib/curly/template_handler.rb
127
128
  - lib/generators/curly/controller/controller_generator.rb
128
129
  - lib/generators/curly/controller/templates/presenter.rb.erb
@@ -133,6 +134,7 @@ files:
133
134
  - spec/presenter_spec.rb
134
135
  - spec/scanner_spec.rb
135
136
  - spec/spec_helper.rb
137
+ - spec/syntax_error_spec.rb
136
138
  - spec/template_handler_spec.rb
137
139
  homepage: https://github.com/zendesk/curly
138
140
  licenses:
@@ -150,7 +152,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
152
  version: '0'
151
153
  segments:
152
154
  - 0
153
- hash: -1930897478710122249
155
+ hash: 1896340551249669380
154
156
  required_rubygems_version: !ruby/object:Gem::Requirement
155
157
  none: false
156
158
  requirements:
@@ -168,5 +170,6 @@ test_files:
168
170
  - spec/generators/controller_generator_spec.rb
169
171
  - spec/presenter_spec.rb
170
172
  - spec/scanner_spec.rb
173
+ - spec/syntax_error_spec.rb
171
174
  - spec/template_handler_spec.rb
172
175
  has_rdoc: