puppet 3.8.1 → 3.8.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/ext/build_defaults.yaml +4 -4
- data/ext/systemd/puppet.service +1 -1
- data/ext/systemd/puppetmaster.service +1 -1
- data/lib/hiera/puppet_function.rb +5 -5
- data/lib/puppet/defaults.rb +1 -5
- data/lib/puppet/environments.rb +85 -4
- data/lib/puppet/functions/hiera_include.rb +2 -2
- data/lib/puppet/module_tool/applications/unpacker.rb +1 -1
- data/lib/puppet/parser/ast/collexpr.rb +1 -1
- data/lib/puppet/parser/ast/pops_bridge.rb +5 -0
- data/lib/puppet/parser/scope.rb +43 -13
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -1
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +1 -1
- data/lib/puppet/pops/evaluator/runtime3_support.rb +31 -0
- data/lib/puppet/pops/issues.rb +10 -2
- data/lib/puppet/pops/model/factory.rb +4 -3
- data/lib/puppet/pops/model/model_meta.rb +4 -1
- data/lib/puppet/pops/parser/egrammar.ra +4 -0
- data/lib/puppet/pops/parser/eparser.rb +1167 -1066
- data/lib/puppet/pops/parser/epp_support.rb +4 -2
- data/lib/puppet/pops/parser/lexer2.rb +6 -0
- data/lib/puppet/pops/patterns.rb +3 -0
- data/lib/puppet/pops/types/type_parser.rb +2 -2
- data/lib/puppet/pops/validation/checker4_0.rb +9 -1
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +3 -1
- data/lib/puppet/provider/group/pw.rb +1 -0
- data/lib/puppet/provider/service/debian.rb +2 -1
- data/lib/puppet/provider/user/pw.rb +1 -0
- data/lib/puppet/resource.rb +3 -1
- data/lib/puppet/resource/type.rb +4 -2
- data/lib/puppet/util.rb +9 -1
- data/lib/puppet/util/log.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/spec/integration/parser/compiler_spec.rb +9 -7
- data/spec/integration/parser/future_compiler_spec.rb +9 -7
- data/spec/integration/parser/scope_spec.rb +37 -0
- data/spec/unit/environments_spec.rb +2 -0
- data/spec/unit/functions/hiera_spec.rb +2 -2
- data/spec/unit/parser/scope_spec.rb +9 -0
- data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +19 -0
- data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +48 -3
- data/spec/unit/pops/types/type_parser_spec.rb +8 -0
- data/spec/unit/pops/validator/validator_spec.rb +28 -0
- data/spec/unit/provider/service/debian_spec.rb +11 -3
- data/spec/unit/provider/zone/solaris_spec.rb +45 -12
- data/spec/unit/util/log_spec.rb +12 -1
- data/spec/unit/util_spec.rb +21 -2
- metadata +3283 -3273
- checksums.yaml +0 -7
@@ -183,7 +183,7 @@ module Puppet::Pops::Parser::EppSupport
|
|
183
183
|
until scanner.eos?
|
184
184
|
part = @scanner.scan_until(/(<%)|\z/)
|
185
185
|
if @skip_leading
|
186
|
-
part.
|
186
|
+
part.sub!(/^[ \t]*\r?(?:\n|\z)?/,'')
|
187
187
|
@skip_leading = false
|
188
188
|
end
|
189
189
|
# The spec for %%> is to transform it into a literal %>. This is done here, as %%> otherwise would go
|
@@ -208,7 +208,7 @@ module Puppet::Pops::Parser::EppSupport
|
|
208
208
|
# trim trailing whitespace on same line from accumulated s
|
209
209
|
# return text and signal switch to pp mode
|
210
210
|
@scanner.getch # drop the -
|
211
|
-
s.
|
211
|
+
s.sub!(/[ \t]*<%\z/, '')
|
212
212
|
@mode = :epp
|
213
213
|
return s
|
214
214
|
|
@@ -240,6 +240,8 @@ module Puppet::Pops::Parser::EppSupport
|
|
240
240
|
@mode = :error
|
241
241
|
return s
|
242
242
|
end
|
243
|
+
# Always trim leading whitespace on the same line when there is a comment
|
244
|
+
s.sub!(/[ \t]*\z/, '')
|
243
245
|
@skip_leading = true if part.end_with?("-%>")
|
244
246
|
# Continue scanning for more text
|
245
247
|
|
@@ -131,7 +131,13 @@ class Puppet::Pops::Parser::Lexer2
|
|
131
131
|
"type" => [:TYPE, 'type', 4],
|
132
132
|
"attr" => [:ATTR, 'attr', 4],
|
133
133
|
"private" => [:PRIVATE, 'private', 7],
|
134
|
+
# The following tokens exist in reserved form. Later they will be made
|
135
|
+
# live subject to a feature switch.
|
136
|
+
"application" => [:APPLICATION_R, 'application', 11],
|
137
|
+
"consumes" => [:CONSUMES_R, 'consumes', 8],
|
138
|
+
"produces" => [:PRODUCES_R, 'produces', 8],
|
134
139
|
}
|
140
|
+
|
135
141
|
KEYWORDS.each {|k,v| v[1].freeze; v.freeze }
|
136
142
|
KEYWORDS.freeze
|
137
143
|
|
data/lib/puppet/pops/patterns.rb
CHANGED
@@ -38,6 +38,9 @@ module Puppet::Pops::Patterns
|
|
38
38
|
# Note, that only the final segment may start with an underscore.
|
39
39
|
VAR_NAME = %r{\A(:?(::)?[a-z]\w*)*(:?(::)?[a-z_]\w*)\z}
|
40
40
|
|
41
|
+
# PARAM_NAME matches the name part of a parameter (The $ character is not included)
|
42
|
+
PARAM_NAME = %r{\A[a-z_]\w*\z}
|
43
|
+
|
41
44
|
# A Numeric var name must be the decimal number 0, or a decimal number not starting with 0
|
42
45
|
NUMERIC_VAR_NAME = %r{\A(?:0|(?:[1-9][0-9]*))\z}
|
43
46
|
|
@@ -356,7 +356,7 @@ class Puppet::Pops::Types::TypeParser
|
|
356
356
|
if parameters.size == 1
|
357
357
|
case parameters[0]
|
358
358
|
when Integer
|
359
|
-
TYPES.range(parameters[0],
|
359
|
+
TYPES.range(parameters[0], :default)
|
360
360
|
when :default
|
361
361
|
TYPES.integer # unbound
|
362
362
|
end
|
@@ -370,7 +370,7 @@ class Puppet::Pops::Types::TypeParser
|
|
370
370
|
if parameters.size == 1
|
371
371
|
case parameters[0]
|
372
372
|
when Integer, Float
|
373
|
-
TYPES.float_range(parameters[0],
|
373
|
+
TYPES.float_range(parameters[0], :default)
|
374
374
|
when :default
|
375
375
|
TYPES.float # unbound
|
376
376
|
end
|
@@ -427,6 +427,10 @@ class Puppet::Pops::Validation::Checker4_0
|
|
427
427
|
if o.name =~ /^(?:0x)?[0-9]+$/
|
428
428
|
acceptor.accept(Issues::ILLEGAL_NUMERIC_PARAMETER, o, :name => o.name)
|
429
429
|
end
|
430
|
+
|
431
|
+
unless o.name =~ Puppet::Pops::Patterns::PARAM_NAME
|
432
|
+
acceptor.accept(Issues::ILLEGAL_PARAM_NAME, o, :name => o.name)
|
433
|
+
end
|
430
434
|
end
|
431
435
|
|
432
436
|
#relationship_side: resource
|
@@ -476,7 +480,11 @@ class Puppet::Pops::Validation::Checker4_0
|
|
476
480
|
end
|
477
481
|
|
478
482
|
def check_ReservedWord(o)
|
479
|
-
|
483
|
+
if o.future
|
484
|
+
acceptor.accept(Issues::FUTURE_RESERVED_WORD, o, :word => o.word)
|
485
|
+
else
|
486
|
+
acceptor.accept(Issues::RESERVED_WORD, o, :word => o.word)
|
487
|
+
end
|
480
488
|
end
|
481
489
|
|
482
490
|
def check_SelectorExpression(o)
|
@@ -23,7 +23,9 @@ class Puppet::Pops::Validation::ValidatorFactory_4_0 < Puppet::Pops::Validation:
|
|
23
23
|
p[Issues::RT_NO_STORECONFIGS_EXPORT] = Puppet[:storeconfigs] ? :ignore : :warning
|
24
24
|
p[Issues::RT_NO_STORECONFIGS] = Puppet[:storeconfigs] ? :ignore : :warning
|
25
25
|
|
26
|
-
p[Issues::
|
26
|
+
p[Issues::FUTURE_RESERVED_WORD] = :deprecation
|
27
|
+
|
28
|
+
p[Issues::NAME_WITH_HYPHEN] = :error
|
27
29
|
p[Issues::EMPTY_RESOURCE_SPECIALIZATION] = :ignore
|
28
30
|
p
|
29
31
|
end
|
@@ -7,6 +7,7 @@ Puppet::Type.type(:group).provide :pw, :parent => Puppet::Provider::NameService:
|
|
7
7
|
has_features :manages_members
|
8
8
|
|
9
9
|
defaultfor :operatingsystem => [:freebsd, :dragonfly]
|
10
|
+
confine :operatingsystem => [:freebsd, :dragonfly]
|
10
11
|
|
11
12
|
options :members, :flag => "-M", :method => :mem
|
12
13
|
|
@@ -38,7 +38,8 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
|
|
38
38
|
# See x-man-page://invoke-rc.d
|
39
39
|
if [104, 106].include?($CHILD_STATUS.exitstatus)
|
40
40
|
return :true
|
41
|
-
elsif [105].include?($CHILD_STATUS.exitstatus)
|
41
|
+
elsif [101, 105].include?($CHILD_STATUS.exitstatus)
|
42
|
+
# 101 is action not allowed, which means we have to do the check manually.
|
42
43
|
# 105 is unknown, which generally means the iniscript does not support query
|
43
44
|
# The debian policy states that the initscript should support methods of query
|
44
45
|
# For those that do not, peform the checks manually
|
@@ -8,6 +8,7 @@ Puppet::Type.type(:user).provide :pw, :parent => Puppet::Provider::NameService::
|
|
8
8
|
has_features :manages_homedir, :allows_duplicates, :manages_passwords, :manages_expiry, :manages_shell
|
9
9
|
|
10
10
|
defaultfor :operatingsystem => [:freebsd, :dragonfly]
|
11
|
+
confine :operatingsystem => [:freebsd, :dragonfly]
|
11
12
|
|
12
13
|
options :home, :flag => "-d", :method => :dir
|
13
14
|
options :comment, :method => :gecos
|
data/lib/puppet/resource.rb
CHANGED
@@ -430,6 +430,8 @@ class Puppet::Resource
|
|
430
430
|
result.environment = environment
|
431
431
|
result.instance_variable_set(:@rstype, resource_type)
|
432
432
|
|
433
|
+
future_parser_not_in_use = !Puppet.future_parser?(result.environment)
|
434
|
+
|
433
435
|
to_hash.each do |p, v|
|
434
436
|
if v.is_a?(Puppet::Resource)
|
435
437
|
v = Puppet::Resource.new(v.type, v.title)
|
@@ -442,7 +444,7 @@ class Puppet::Resource
|
|
442
444
|
end
|
443
445
|
end
|
444
446
|
|
445
|
-
if !Puppet.future_parser?
|
447
|
+
if future_parser_not_in_use # !Puppet.future_parser?
|
446
448
|
# If the value is an array with only one value, then
|
447
449
|
# convert it to a single value. This is largely so that
|
448
450
|
# the database interaction doesn't have to worry about
|
data/lib/puppet/resource/type.rb
CHANGED
@@ -82,8 +82,10 @@ class Puppet::Resource::Type
|
|
82
82
|
|
83
83
|
# External documentation uses "parameters" but the internal name
|
84
84
|
# is "arguments"
|
85
|
-
|
86
|
-
|
85
|
+
# Dump any arguments as source
|
86
|
+
data['parameters'] = Hash[arguments.map do |k,v|
|
87
|
+
[k, v.respond_to?(:source_text) ? v.source_text : v]
|
88
|
+
end]
|
87
89
|
data['name'] = name
|
88
90
|
|
89
91
|
unless RESOURCE_KINDS_TO_EXTERNAL_NAMES.has_key?(type)
|
data/lib/puppet/util.rb
CHANGED
@@ -292,7 +292,15 @@ module Util
|
|
292
292
|
$stdout.reopen(stdout)
|
293
293
|
$stderr.reopen(stderr)
|
294
294
|
|
295
|
-
|
295
|
+
begin
|
296
|
+
Dir.foreach('/proc/self/fd') do |f|
|
297
|
+
if f != '.' && f != '..' && f.to_i >= 3
|
298
|
+
IO::new(f.to_i).close rescue nil
|
299
|
+
end
|
300
|
+
end
|
301
|
+
rescue Errno::ENOENT # /proc/self/fd not found
|
302
|
+
3.upto(256){|fd| IO::new(fd).close rescue nil}
|
303
|
+
end
|
296
304
|
|
297
305
|
block.call if block
|
298
306
|
end
|
data/lib/puppet/util/log.rb
CHANGED
@@ -336,7 +336,7 @@ class Puppet::Util::Log
|
|
336
336
|
# If they pass a source in to us, we make sure it is a string, and
|
337
337
|
# we retrieve any tags we can.
|
338
338
|
def source=(source)
|
339
|
-
if source.
|
339
|
+
if defined?(Puppet::Type) && source.is_a?(Puppet::Type)
|
340
340
|
@source = source.path
|
341
341
|
source.tags.each { |t| tag(t) }
|
342
342
|
self.file = source.file
|
data/lib/puppet/version.rb
CHANGED
@@ -121,15 +121,17 @@ describe "Puppet::Parser::Compiler" do
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
it
|
124
|
+
it 'should recompute the version after input files are re-parsed' do
|
125
125
|
Puppet[:code] = 'class foo { }'
|
126
|
-
Time.
|
126
|
+
first_time = Time.at(1)
|
127
|
+
second_time = Time.at(200)
|
128
|
+
Time.stubs(:now).returns(first_time)
|
127
129
|
node = Puppet::Node.new('mynode')
|
128
|
-
Puppet::Parser::Compiler.compile(node).version.
|
129
|
-
Time.stubs(:now).returns(
|
130
|
-
Puppet::Parser::Compiler.compile(node).version.
|
131
|
-
Puppet
|
132
|
-
Puppet::Parser::Compiler.compile(node).version.
|
130
|
+
expect(Puppet::Parser::Compiler.compile(node).version).to eq(first_time.to_i)
|
131
|
+
Time.stubs(:now).returns(second_time)
|
132
|
+
expect(Puppet::Parser::Compiler.compile(node).version).to eq(first_time.to_i) # no change because files didn't change
|
133
|
+
Puppet[:code] = nil
|
134
|
+
expect(Puppet::Parser::Compiler.compile(node).version).to eq(second_time.to_i)
|
133
135
|
end
|
134
136
|
|
135
137
|
['class', 'define', 'node'].each do |thing|
|
@@ -185,15 +185,17 @@ describe "Puppet::Parser::Compiler" do
|
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
188
|
-
it
|
188
|
+
it 'should recompute the version after input files are re-parsed' do
|
189
189
|
Puppet[:code] = 'class foo { }'
|
190
|
-
Time.
|
190
|
+
first_time = Time.at(1)
|
191
|
+
second_time = Time.at(200)
|
192
|
+
Time.stubs(:now).returns(first_time)
|
191
193
|
node = Puppet::Node.new('mynode')
|
192
|
-
Puppet::Parser::Compiler.compile(node).version.
|
193
|
-
Time.stubs(:now).returns(
|
194
|
-
Puppet::Parser::Compiler.compile(node).version.
|
195
|
-
Puppet
|
196
|
-
Puppet::Parser::Compiler.compile(node).version.
|
194
|
+
expect(Puppet::Parser::Compiler.compile(node).version).to eq(first_time.to_i)
|
195
|
+
Time.stubs(:now).returns(second_time)
|
196
|
+
expect(Puppet::Parser::Compiler.compile(node).version).to eq(first_time.to_i) # no change because files didn't change
|
197
|
+
Puppet[:code] = nil
|
198
|
+
expect(Puppet::Parser::Compiler.compile(node).version).to eq(second_time.to_i)
|
197
199
|
end
|
198
200
|
|
199
201
|
['define', 'class', 'node'].each do |thing|
|
@@ -32,6 +32,25 @@ describe "Two step scoping for variables" do
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
describe 'handles 3.x/4.x functions' do
|
37
|
+
it 'can call a 3.x function via call_function' do
|
38
|
+
expect_the_message_to_be('yes') do <<-MANIFEST
|
39
|
+
$msg = inline_template('<%= scope().call_function("fqdn_rand", [30]).to_i <= 30 ? "yes" : "no" %>')
|
40
|
+
notify { 'something': message => $msg }
|
41
|
+
MANIFEST
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'can cannot call a 4.x function via call_function' do
|
46
|
+
expect do
|
47
|
+
catalog = compile_to_catalog(<<-MANIFEST)
|
48
|
+
$msg = inline_template('<%= scope().call_function("with", ["yes"]) { |x| x } %>')
|
49
|
+
notify { 'something': message => $msg }
|
50
|
+
MANIFEST
|
51
|
+
end.to raise_error
|
52
|
+
end
|
53
|
+
end
|
35
54
|
end
|
36
55
|
|
37
56
|
context 'using future parser' do
|
@@ -120,6 +139,24 @@ describe "Two step scoping for variables" do
|
|
120
139
|
MANIFEST
|
121
140
|
end
|
122
141
|
end
|
142
|
+
|
143
|
+
describe 'handles 3.x/4.x functions' do
|
144
|
+
it 'can call a 3.x function via call_function' do
|
145
|
+
expect_the_message_to_be('yes') do <<-MANIFEST
|
146
|
+
$msg = inline_template('<%= scope().call_function("fqdn_rand", [30]).to_i <= 30 ? "yes" : "no" %>')
|
147
|
+
notify { 'something': message => $msg }
|
148
|
+
MANIFEST
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'it can call a 4.x function via call_function' do
|
153
|
+
expect_the_message_to_be('yes') do <<-MANIFEST
|
154
|
+
$msg = inline_template('<%= scope().call_function("with", ["yes"]) { |x| x } %>')
|
155
|
+
notify { 'something': message => $msg }
|
156
|
+
MANIFEST
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
123
160
|
end
|
124
161
|
|
125
162
|
shared_examples_for "the scope" do
|
@@ -112,7 +112,7 @@ describe 'when calling' do
|
|
112
112
|
|
113
113
|
it 'should use the array resolution_type' do
|
114
114
|
Hiera.any_instance.expects(:lookup).with { |*args| args[4].should be(:array) }.returns(%w[foo bar baz])
|
115
|
-
hiera_include.expects(:
|
115
|
+
hiera_include.expects(:call_function_with_scope).with(scope, 'include', %w[foo bar baz])
|
116
116
|
hiera_include.call(scope, 'key', {'key' => 'foo_result'})
|
117
117
|
end
|
118
118
|
|
@@ -122,7 +122,7 @@ describe 'when calling' do
|
|
122
122
|
end
|
123
123
|
|
124
124
|
it 'should use default block' do
|
125
|
-
hiera_include.expects(:
|
125
|
+
hiera_include.expects(:call_function_with_scope).with(scope,'include', %w[key foo])
|
126
126
|
hiera_include.call(scope, 'foo') { |k| ['key', k] }
|
127
127
|
end
|
128
128
|
end
|
@@ -33,6 +33,15 @@ describe Puppet::Parser::Scope do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
it "should generate a simple string when inspecting a scope" do
|
37
|
+
@scope.inspect.should eq("Scope()")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should generate a simple string when inspecting a scope with a resource" do
|
41
|
+
@scope.resource="foo::bar"
|
42
|
+
@scope.inspect.should eq("Scope(foo::bar)")
|
43
|
+
end
|
44
|
+
|
36
45
|
it "should return a scope for use in a test harness" do
|
37
46
|
create_test_scope_for_node("node_name_foo").should be_a_kind_of(Puppet::Parser::Scope)
|
38
47
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
require 'puppet/pops'
|
5
|
+
require 'puppet/pops/types/type_factory'
|
6
|
+
|
7
|
+
describe 'when converting to 3.x' do
|
8
|
+
it "converts a resource type starting with Class without confusing it with exact match on 'class'" do
|
9
|
+
t = Puppet::Pops::Types::TypeFactory.resource('classroom', 'kermit')
|
10
|
+
converted = Puppet::Pops::Evaluator::Runtime3Converter.instance.catalog_type_to_split_type_title(t)
|
11
|
+
expect(converted).to eql(['classroom', 'kermit'])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "converts a resource type of exactly 'Class'" do
|
15
|
+
t = Puppet::Pops::Types::TypeFactory.resource('class', 'kermit')
|
16
|
+
converted = Puppet::Pops::Evaluator::Runtime3Converter.instance.catalog_type_to_split_type_title(t)
|
17
|
+
expect(converted).to eql(['class', 'kermit'])
|
18
|
+
end
|
19
|
+
end
|
@@ -41,7 +41,7 @@ describe 'Puppet::Pops::Impl::EvaluatorImpl' do
|
|
41
41
|
|
42
42
|
it "access to global names works in local scope" do
|
43
43
|
top_scope_block = block( var('a').set(literal(2)+literal(2)))
|
44
|
-
local_scope_block = block( var('a').set(var('::a')+literal(2)), var('
|
44
|
+
local_scope_block = block( var('a').set(literal(100)), var('b').set(var('::a')+literal(2)), var('b'))
|
45
45
|
evaluate_l(top_scope_block, local_scope_block).should == 6
|
46
46
|
end
|
47
47
|
|
@@ -91,12 +91,25 @@ describe 'Lexer2' do
|
|
91
91
|
"true" => :BOOLEAN,
|
92
92
|
"in" => :IN,
|
93
93
|
"unless" => :UNLESS,
|
94
|
+
"private" => :PRIVATE,
|
95
|
+
"type" => :TYPE,
|
96
|
+
"attr" => :ATTR,
|
94
97
|
}.each do |string, name|
|
95
98
|
it "should lex a keyword from '#{string}'" do
|
96
99
|
tokens_scanned_from(string).should match_tokens2(name)
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
103
|
+
{
|
104
|
+
"application" => :APPLICATION_R,
|
105
|
+
"consumes" => :CONSUMES_R,
|
106
|
+
"produces" => :PRODUCES_R,
|
107
|
+
}.each do |string, name|
|
108
|
+
it "should lex a (future reserved) keyword from '#{string}'" do
|
109
|
+
tokens_scanned_from(string).should match_tokens2(name)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
100
113
|
# TODO: Complete with all edge cases
|
101
114
|
[ 'A', 'A::B', '::A', '::A::B',].each do |string|
|
102
115
|
it "should lex a CLASSREF on the form '#{string}'" do
|
@@ -535,7 +548,7 @@ describe 'Lexer2' do
|
|
535
548
|
[:VARIABLE, "x"],
|
536
549
|
:EQUALS,
|
537
550
|
[:NUMBER, "10"],
|
538
|
-
[:RENDER_STRING, "just text\n"]
|
551
|
+
[:RENDER_STRING, " just text\n"]
|
539
552
|
)
|
540
553
|
end
|
541
554
|
|
@@ -551,7 +564,39 @@ describe 'Lexer2' do
|
|
551
564
|
[:VARIABLE, "x"],
|
552
565
|
:EQUALS,
|
553
566
|
[:NUMBER, "10"],
|
554
|
-
[:RENDER_STRING, "just text\n"]
|
567
|
+
[:RENDER_STRING, " just text\n"]
|
568
|
+
)
|
569
|
+
end
|
570
|
+
|
571
|
+
it 'epp comments strips left whitespace when preceding is right trim' do
|
572
|
+
code = <<-CODE
|
573
|
+
This is <% $x=10 -%>
|
574
|
+
space-before-me-but-not-after <%# This is an epp comment %>
|
575
|
+
just text
|
576
|
+
CODE
|
577
|
+
expect(epp_tokens_scanned_from(code)).to match_tokens2(
|
578
|
+
:EPP_START,
|
579
|
+
[:RENDER_STRING, " This is "],
|
580
|
+
[:VARIABLE, "x"],
|
581
|
+
:EQUALS,
|
582
|
+
[:NUMBER, "10"],
|
583
|
+
[:RENDER_STRING, " space-before-me-but-not-after\n just text\n"]
|
584
|
+
)
|
585
|
+
end
|
586
|
+
|
587
|
+
it 'epp comments strips left whitespace on same line when preceding is not right trim' do
|
588
|
+
code = <<-CODE
|
589
|
+
This is <% $x=10 %>
|
590
|
+
<%# This is an epp comment -%>
|
591
|
+
just text
|
592
|
+
CODE
|
593
|
+
expect(epp_tokens_scanned_from(code)).to match_tokens2(
|
594
|
+
:EPP_START,
|
595
|
+
[:RENDER_STRING, " This is "],
|
596
|
+
[:VARIABLE, "x"],
|
597
|
+
:EQUALS,
|
598
|
+
[:NUMBER, "10"],
|
599
|
+
[:RENDER_STRING, "\n just text\n"]
|
555
600
|
)
|
556
601
|
end
|
557
602
|
|
@@ -566,7 +611,7 @@ describe 'Lexer2' do
|
|
566
611
|
[:VARIABLE, "x"],
|
567
612
|
:EQUALS,
|
568
613
|
[:NUMBER, "10"],
|
569
|
-
[:RENDER_STRING, "<% this is escaped epp %>\n"]
|
614
|
+
[:RENDER_STRING, " <% this is escaped epp %>\n"]
|
570
615
|
)
|
571
616
|
end
|
572
617
|
|