curly-templates 0.10.2 → 0.11.0

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