flavour_saver 1.0.0 → 2.0.2
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +21 -0
- data/CHANGELOG.md +33 -0
- data/Gemfile.lock +2 -2
- data/flavour_saver.gemspec +1 -1
- data/lib/flavour_saver/helpers.rb +26 -12
- data/lib/flavour_saver/lexer.rb +1 -1
- data/lib/flavour_saver/parser.rb +14 -8
- data/lib/flavour_saver/runtime.rb +2 -2
- data/lib/flavour_saver/version.rb +1 -1
- data/lib/flavour_saver.rb +3 -2
- data/spec/acceptance/handlebars_qunit_spec.rb +78 -0
- data/spec/acceptance/if_else_spec.rb +37 -6
- data/spec/acceptance/unless_spec.rb +48 -0
- data/spec/fixtures/if_else.hbs +3 -3
- data/spec/fixtures/unless.hbs +5 -0
- data/spec/lib/flavour_saver/lexer_spec.rb +31 -0
- metadata +12 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5bd75dc7f4e17072e0e18ffdefdfa81c6f24e98859786bb37c45191095964f2c
|
|
4
|
+
data.tar.gz: 41ac8be61e4a0969a7aa669a7f1cb488530f8a4d5514aca979fa37da151aca32
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d771d2bdc69eea05f39b747299a962f914a53a3e1475a26089ea951eef505acd5d7e8511b9fd1d61e2d22cdceaf3bd52e7b7326901c3cd7cdb1216eb3c4ba4d2
|
|
7
|
+
data.tar.gz: ba14f4e5d4c62ace6ae2c8a1776cd8f7d9757333a1545473169d5f3c7f12c621149804736c1ff453927d8ed87b6ed31c756df8aee53cde2c54c2a094eefd2cb5
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -3,6 +3,7 @@ name: Continuous integration
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches: [ master ]
|
|
6
|
+
tags: [ 'v*' ]
|
|
6
7
|
pull_request:
|
|
7
8
|
branches: [ master ]
|
|
8
9
|
|
|
@@ -24,3 +25,23 @@ jobs:
|
|
|
24
25
|
- name: Run tests
|
|
25
26
|
run: bundle exec rspec
|
|
26
27
|
|
|
28
|
+
publish-gem:
|
|
29
|
+
if: github.ref_type == 'tag'
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
needs: [test]
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v2
|
|
34
|
+
- name: Set up Ruby 2.7
|
|
35
|
+
uses: ruby/setup-ruby@v1
|
|
36
|
+
with:
|
|
37
|
+
ruby-version: 2.7
|
|
38
|
+
- name: Publish to RubyGems
|
|
39
|
+
run: |
|
|
40
|
+
mkdir -p $HOME/.gem
|
|
41
|
+
touch $HOME/.gem/credentials
|
|
42
|
+
chmod 0600 $HOME/.gem/credentials
|
|
43
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
44
|
+
gem build *.gemspec
|
|
45
|
+
gem push *.gem
|
|
46
|
+
env:
|
|
47
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.2]
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
* Deprecation warning for template handler (#59)
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
* Relaxed version constraint on activesupport dependency (#60)
|
|
19
|
+
|
|
20
|
+
## [2.0.1]
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
* Ability to dereference arrays at a specific index (#57)
|
|
25
|
+
|
|
26
|
+
## [2.0.0]
|
|
27
|
+
|
|
28
|
+
### Breaking Changes
|
|
29
|
+
|
|
30
|
+
* The #if and #unless helpers now treat zero as falsey (#54, #55)
|
|
31
|
+
* The #unless helper now treats empty objects as falsey (#55)
|
|
32
|
+
* Using #each on a hash now yields the value instead of an array of key, value (#52)
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
* Support for @root object (#49)
|
|
37
|
+
* Support for @key object inside #each blocks with Hashes (#52)
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
* Lex number literals that start with 0 (#53)
|
|
42
|
+
|
|
10
43
|
## [1.0.0] - 2022-01-19
|
|
11
44
|
|
|
12
45
|
### Added
|
data/Gemfile.lock
CHANGED
data/flavour_saver.gemspec
CHANGED
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |gem|
|
|
|
26
26
|
|
|
27
27
|
gem.add_development_dependency 'rake'
|
|
28
28
|
gem.add_development_dependency 'rspec'
|
|
29
|
-
gem.add_development_dependency 'activesupport', '<
|
|
29
|
+
gem.add_development_dependency 'activesupport', '< 8.0'
|
|
30
30
|
|
|
31
31
|
gem.add_dependency 'rltk', '~> 2.2.0'
|
|
32
32
|
gem.add_dependency 'tilt'
|
|
@@ -11,27 +11,31 @@ module FlavourSaver
|
|
|
11
11
|
r = []
|
|
12
12
|
count = 0
|
|
13
13
|
collection.each do |element|
|
|
14
|
-
|
|
15
|
-
'index' => count,
|
|
16
|
-
'last' => count == collection.size - 1,
|
|
17
|
-
'first' => count == 0
|
|
14
|
+
locals ={
|
|
15
|
+
'index' => count,
|
|
16
|
+
'last' => count == collection.size - 1,
|
|
17
|
+
'first' => count == 0
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
locals['key'], element = element if collection.is_a?(Hash)
|
|
21
|
+
|
|
22
|
+
r << yield.contents(element, locals)
|
|
18
23
|
count += 1
|
|
19
24
|
end
|
|
20
25
|
yield.rendered!
|
|
21
26
|
r.join ''
|
|
22
27
|
end
|
|
23
28
|
|
|
24
|
-
def if(
|
|
25
|
-
|
|
26
|
-
if truthy
|
|
29
|
+
def if(value)
|
|
30
|
+
if truthy?(value)
|
|
27
31
|
yield.contents
|
|
28
32
|
else
|
|
29
33
|
yield.inverse
|
|
30
34
|
end
|
|
31
35
|
end
|
|
32
36
|
|
|
33
|
-
def unless(
|
|
34
|
-
self.if(!
|
|
37
|
+
def unless(value, &b)
|
|
38
|
+
self.if(!truthy?(value), &b)
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
def this
|
|
@@ -42,6 +46,16 @@ module FlavourSaver
|
|
|
42
46
|
FS.logger.debug("FlavourSaver: #{message}")
|
|
43
47
|
''
|
|
44
48
|
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
# Think of this as a compatability layer to make Ruby conditionals
|
|
53
|
+
# behave like JavaScript conditionals.
|
|
54
|
+
def truthy?(value)
|
|
55
|
+
value = false if value.respond_to?(:size) && (value.size == 0)
|
|
56
|
+
value = false if value.respond_to?(:zero?) && value.zero?
|
|
57
|
+
value
|
|
58
|
+
end
|
|
45
59
|
end
|
|
46
60
|
|
|
47
61
|
class Decorator < Defaults
|
|
@@ -107,10 +121,10 @@ module FlavourSaver
|
|
|
107
121
|
|
|
108
122
|
def decorate_with(context, helper_names=[], locals={})
|
|
109
123
|
helpers = if helper_names.any?
|
|
110
|
-
|
|
111
|
-
registered_helpers.select { |k,v|
|
|
124
|
+
helper_symbols = helper_names.map(&:to_sym)
|
|
125
|
+
registered_helpers.select { |k,v| helper_symbols.member? k }
|
|
112
126
|
else
|
|
113
|
-
|
|
127
|
+
registered_helpers
|
|
114
128
|
end
|
|
115
129
|
helpers = helpers.merge(locals)
|
|
116
130
|
Decorator.new(helpers, context)
|
data/lib/flavour_saver/lexer.rb
CHANGED
data/lib/flavour_saver/parser.rb
CHANGED
|
@@ -115,7 +115,6 @@ module FlavourSaver
|
|
|
115
115
|
|
|
116
116
|
production(:expression_contents) do
|
|
117
117
|
clause('WHITE? call WHITE?') { |_,e,_| e }
|
|
118
|
-
clause('WHITE? local WHITE?') { |_,e,_| [e] }
|
|
119
118
|
end
|
|
120
119
|
|
|
121
120
|
production(:call) do
|
|
@@ -124,17 +123,13 @@ module FlavourSaver
|
|
|
124
123
|
clause('DOT') { |_| [CallNode.new('this', [])] }
|
|
125
124
|
end
|
|
126
125
|
|
|
127
|
-
production(:local) do
|
|
128
|
-
clause('AT IDENT') { |_,e| LocalVarNode.new(e) }
|
|
129
|
-
end
|
|
130
|
-
|
|
131
126
|
production('arguments') do
|
|
132
127
|
clause('argument_list') { |e| e }
|
|
133
128
|
clause('argument_list WHITE hash') { |e0,_,e1| e0 + [e1] }
|
|
134
129
|
clause('hash') { |e| [e] }
|
|
135
130
|
end
|
|
136
|
-
|
|
137
|
-
nonempty_list(:argument_list, [:object_path
|
|
131
|
+
|
|
132
|
+
nonempty_list(:argument_list, [:object_path, :lit, :subexpr], :WHITE)
|
|
138
133
|
|
|
139
134
|
production(:lit) do
|
|
140
135
|
clause('string') { |e| e }
|
|
@@ -172,9 +167,20 @@ module FlavourSaver
|
|
|
172
167
|
clause('FWSL') { |_| }
|
|
173
168
|
end
|
|
174
169
|
|
|
175
|
-
|
|
170
|
+
production(:object_path) do
|
|
171
|
+
clause('object') { |e| [e] }
|
|
172
|
+
clause('object_path object_sep object') { |e0,_,e1| e0 + [e1] }
|
|
173
|
+
|
|
174
|
+
# Accomodates objects dereferenced with a number like foo.0.text
|
|
175
|
+
clause('object_path object_sep number_object') { |e0,_,e1| e0 + [e1] }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
production(:number_object) do
|
|
179
|
+
clause('NUMBER') { |e| LiteralCallNode.new(e, []) }
|
|
180
|
+
end
|
|
176
181
|
|
|
177
182
|
production(:object) do
|
|
183
|
+
clause('AT IDENT') { |_,e| LocalVarNode.new(e) }
|
|
178
184
|
clause('IDENT') { |e| CallNode.new(e, []) }
|
|
179
185
|
clause('LITERAL') { |e| LiteralCallNode.new(e, []) }
|
|
180
186
|
clause('parent_call') { |e| e }
|
|
@@ -8,7 +8,7 @@ module FlavourSaver
|
|
|
8
8
|
UnknownHelperException = Class.new(RuntimeError)
|
|
9
9
|
class Runtime
|
|
10
10
|
|
|
11
|
-
attr_accessor :context, :parent, :ast
|
|
11
|
+
attr_accessor :context, :parent, :ast, :privates
|
|
12
12
|
|
|
13
13
|
def self.run(ast, context, locals={}, helpers=[])
|
|
14
14
|
self.new(ast, context, locals, helpers).to_s
|
|
@@ -20,7 +20,7 @@ module FlavourSaver
|
|
|
20
20
|
@helpers = helpers
|
|
21
21
|
@context = context
|
|
22
22
|
@parent = parent
|
|
23
|
-
@privates = {}
|
|
23
|
+
@privates = parent ? parent.privates.dup : { 'root' => context }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def to_s(tmp_context = nil,privates={})
|
data/lib/flavour_saver.rb
CHANGED
|
@@ -17,10 +17,11 @@ module FlavourSaver
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
ActiveSupport.on_load(:action_view) do
|
|
20
|
-
handler = proc do |template|
|
|
20
|
+
handler = proc do |template, source|
|
|
21
|
+
source ||= template.source
|
|
21
22
|
# I'd rather be caching the Runtime object ready to fire, but apparently I don't get that luxury.
|
|
22
23
|
<<-SOURCE
|
|
23
|
-
FlavourSaver.evaluate((begin;#{
|
|
24
|
+
FlavourSaver.evaluate((begin;#{source.inspect};end),self)
|
|
24
25
|
SOURCE
|
|
25
26
|
end
|
|
26
27
|
ActionView::Template.register_template_handler(:hbs, handler)
|
|
@@ -406,6 +406,21 @@ describe FlavourSaver do
|
|
|
406
406
|
end
|
|
407
407
|
end
|
|
408
408
|
|
|
409
|
+
describe 'array with numeric dereference' do
|
|
410
|
+
let(:template) {"{{goodbyes.0.text}} cruel {{world}}!"}
|
|
411
|
+
|
|
412
|
+
it 'properly inserts the referenced element' do
|
|
413
|
+
goodbyes = []
|
|
414
|
+
goodbyes << double(:goodbye)
|
|
415
|
+
expect(goodbyes[0]).to receive(:text).and_return('goodbye')
|
|
416
|
+
|
|
417
|
+
allow(context).to receive(:goodbyes).and_return(goodbyes)
|
|
418
|
+
allow(context).to receive(:world).and_return('world')
|
|
419
|
+
|
|
420
|
+
expect(subject).to eq "goodbye cruel world!"
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
409
424
|
describe 'empty block' do
|
|
410
425
|
let(:template) { "{{#goodbyes}}{{/goodbyes}}cruel {{world}}!" }
|
|
411
426
|
|
|
@@ -909,6 +924,17 @@ describe FlavourSaver do
|
|
|
909
924
|
end
|
|
910
925
|
end
|
|
911
926
|
|
|
927
|
+
describe 'each with @index in a nested block' do
|
|
928
|
+
let(:template) { "{{#each goodbyes}}{{#if @last}}{{@index}}. {{/if}}{{text}}! {{/each}}cruel {{world}}!" }
|
|
929
|
+
|
|
930
|
+
example 'the @index variable is used' do
|
|
931
|
+
g = Struct.new(:text)
|
|
932
|
+
allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
|
|
933
|
+
allow(context).to receive(:world).and_return('world')
|
|
934
|
+
expect(subject).to eq "goodbye! Goodbye! 2. GOODBYE! cruel world!"
|
|
935
|
+
end
|
|
936
|
+
end
|
|
937
|
+
|
|
912
938
|
describe 'each with @last' do
|
|
913
939
|
let(:template) { "{{#each goodbyes}}{{@index}}. {{text}}! {{#if @last}}last{{/if}}{{/each}} cruel {{world}}!" }
|
|
914
940
|
|
|
@@ -931,6 +957,58 @@ describe FlavourSaver do
|
|
|
931
957
|
end
|
|
932
958
|
end
|
|
933
959
|
|
|
960
|
+
describe 'each with @root' do
|
|
961
|
+
let(:template) { "{{#each goodbyes}}{{@index}}. {{text}} cruel {{@root.place}}! {{/each}}" }
|
|
962
|
+
|
|
963
|
+
example 'the root variable is used' do
|
|
964
|
+
g = Struct.new(:text)
|
|
965
|
+
allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
|
|
966
|
+
allow(context).to receive(:place).and_return('world')
|
|
967
|
+
expect(subject).to eq "0. goodbye cruel world! 1. Goodbye cruel world! 2. GOODBYE cruel world! "
|
|
968
|
+
end
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
describe 'each with @root in a nested block' do
|
|
972
|
+
let(:template) { "{{#each goodbyes}}{{@index}}. {{text}}{{#if @last}} cruel {{@root.place}}{{/if}}! {{/each}}" }
|
|
973
|
+
|
|
974
|
+
example 'the root variable is used' do
|
|
975
|
+
g = Struct.new(:text)
|
|
976
|
+
allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
|
|
977
|
+
allow(context).to receive(:place).and_return('world')
|
|
978
|
+
expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE cruel world! "
|
|
979
|
+
end
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
describe 'each with @key' do
|
|
983
|
+
let(:template) { "{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!" }
|
|
984
|
+
|
|
985
|
+
example 'the @key variable is used' do
|
|
986
|
+
g = Struct.new(:text)
|
|
987
|
+
allow(context).to receive(:goodbyes).and_return({
|
|
988
|
+
one: g.new('goodbye'),
|
|
989
|
+
two: g.new('Goodbye'),
|
|
990
|
+
three: g.new('GOODBYE')
|
|
991
|
+
})
|
|
992
|
+
allow(context).to receive(:world).and_return('world')
|
|
993
|
+
expect(subject).to eq "one. goodbye! two. Goodbye! three. GOODBYE! cruel world!"
|
|
994
|
+
end
|
|
995
|
+
end
|
|
996
|
+
|
|
997
|
+
describe 'each with @key in a nested block' do
|
|
998
|
+
let(:template) { "{{#each goodbyes}}{{#if @last}}{{@key}}. {{/if}}{{text}}! {{/each}}cruel {{world}}!" }
|
|
999
|
+
|
|
1000
|
+
example 'the @key variable is used' do
|
|
1001
|
+
g = Struct.new(:text)
|
|
1002
|
+
allow(context).to receive(:goodbyes).and_return({
|
|
1003
|
+
one: g.new('goodbye'),
|
|
1004
|
+
two: g.new('Goodbye'),
|
|
1005
|
+
three: g.new('GOODBYE')
|
|
1006
|
+
})
|
|
1007
|
+
allow(context).to receive(:world).and_return('world')
|
|
1008
|
+
expect(subject).to eq "goodbye! Goodbye! three. GOODBYE! cruel world!"
|
|
1009
|
+
end
|
|
1010
|
+
end
|
|
1011
|
+
|
|
934
1012
|
describe 'log' do
|
|
935
1013
|
let(:template) { "{{log blah}}" }
|
|
936
1014
|
let(:log) { double(:log) }
|
|
@@ -3,15 +3,46 @@ require 'flavour_saver'
|
|
|
3
3
|
|
|
4
4
|
describe 'Fixture: if_else.hbs' do
|
|
5
5
|
subject { Tilt.new(template).render(context).gsub(/[\s\r\n]+/, ' ').strip }
|
|
6
|
-
let(:context) { Struct.new(:
|
|
6
|
+
let(:context) { Struct.new(:value).new }
|
|
7
7
|
let(:template) { File.expand_path('../../fixtures/if_else.hbs', __FILE__) }
|
|
8
8
|
|
|
9
|
-
it
|
|
10
|
-
context.
|
|
11
|
-
expect(subject).to eq "
|
|
9
|
+
it "renders the if block when given a string" do
|
|
10
|
+
context.value = "Alan"
|
|
11
|
+
expect(subject).to eq "The given value is truthy: Alan."
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
it
|
|
15
|
-
|
|
14
|
+
it "renders the if block when given a number greater than zero" do
|
|
15
|
+
context.value = 1
|
|
16
|
+
expect(subject).to eq "The given value is truthy: 1."
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "renders the if block when given an array that is not empty" do
|
|
20
|
+
context.value = [1]
|
|
21
|
+
expect(subject).to eq "The given value is truthy: [1]."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "renders the else block when given false" do
|
|
25
|
+
context.value = false
|
|
26
|
+
expect(subject).to eq "The given value is falsy: false."
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'renders the else block when given nil' do
|
|
30
|
+
context.value = nil
|
|
31
|
+
expect(subject).to eq "The given value is falsy: ."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "renders the else block when given an empty string" do
|
|
35
|
+
context.value = ""
|
|
36
|
+
expect(subject).to eq "The given value is falsy: ."
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "renders the else block when given a zero" do
|
|
40
|
+
context.value = 0
|
|
41
|
+
expect(subject).to eq "The given value is falsy: 0."
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "renders the else block when given an empty array" do
|
|
45
|
+
context.value = []
|
|
46
|
+
expect(subject).to eq "The given value is falsy: []."
|
|
16
47
|
end
|
|
17
48
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'tilt'
|
|
2
|
+
require 'flavour_saver'
|
|
3
|
+
|
|
4
|
+
describe 'Fixture: unless.hbs' do
|
|
5
|
+
subject { Tilt.new(template).render(context).gsub(/[\s\r\n]+/, ' ').strip }
|
|
6
|
+
let(:context) { Struct.new(:value).new }
|
|
7
|
+
let(:template) { File.expand_path('../../fixtures/unless.hbs', __FILE__) }
|
|
8
|
+
|
|
9
|
+
it "renders the unless block when given false" do
|
|
10
|
+
context.value = false
|
|
11
|
+
expect(subject).to eq "The given value is falsy: false."
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'renders the unless block when given nil' do
|
|
15
|
+
context.value = nil
|
|
16
|
+
expect(subject).to eq "The given value is falsy: ."
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "renders the unless block when given an empty string" do
|
|
20
|
+
context.value = ""
|
|
21
|
+
expect(subject).to eq "The given value is falsy: ."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "renders the unless block when given a zero" do
|
|
25
|
+
context.value = 0
|
|
26
|
+
expect(subject).to eq "The given value is falsy: 0."
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "renders the unless block when given an empty array" do
|
|
30
|
+
context.value = []
|
|
31
|
+
expect(subject).to eq "The given value is falsy: []."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "renders the else block when given a string" do
|
|
35
|
+
context.value = "Alan"
|
|
36
|
+
expect(subject).to eq "The given value is truthy: Alan."
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "renders the else block when given a number greater than zero" do
|
|
40
|
+
context.value = 1
|
|
41
|
+
expect(subject).to eq "The given value is truthy: 1."
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "renders the else block when given an array that is not empty" do
|
|
45
|
+
context.value = [1]
|
|
46
|
+
expect(subject).to eq "The given value is truthy: [1]."
|
|
47
|
+
end
|
|
48
|
+
end
|
data/spec/fixtures/if_else.hbs
CHANGED
|
@@ -71,7 +71,38 @@ describe FlavourSaver::Lexer do
|
|
|
71
71
|
it 'has values in the correct order' do
|
|
72
72
|
expect(subject.map(&:value).compact).to eq [ 'foo', 'bar', 'baz', 'hello', 'goodbye' ]
|
|
73
73
|
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '{{0}}' do
|
|
77
|
+
subject { FlavourSaver::Lexer.lex "{{0}}" }
|
|
78
|
+
|
|
79
|
+
it 'properly lexes the expression' do
|
|
80
|
+
expect(subject.map(&:type)).to eq(
|
|
81
|
+
[:EXPRST, :NUMBER, :EXPRE, :EOS]
|
|
82
|
+
)
|
|
83
|
+
end
|
|
74
84
|
|
|
85
|
+
it 'contains only the number "0"' do
|
|
86
|
+
expect(subject[1..-3].size).to eq 1
|
|
87
|
+
expect(subject[1].type).to eq :NUMBER
|
|
88
|
+
expect(subject[1].value).to eq '0'
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe '{{0.0123456789}}' do
|
|
93
|
+
subject { FlavourSaver::Lexer.lex "{{0.0123456789}}" }
|
|
94
|
+
|
|
95
|
+
it 'properly lexes the expression' do
|
|
96
|
+
expect(subject.map(&:type)).to eq(
|
|
97
|
+
[:EXPRST, :NUMBER, :EXPRE, :EOS]
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'contains only the number "0.0123456789"' do
|
|
102
|
+
expect(subject[1..-3].size).to eq 1
|
|
103
|
+
expect(subject[1].type).to eq :NUMBER
|
|
104
|
+
expect(subject[1].value).to eq '0.0123456789'
|
|
105
|
+
end
|
|
75
106
|
end
|
|
76
107
|
end
|
|
77
108
|
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: flavour_saver
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Clayton Passmore
|
|
8
8
|
- James Harton
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2022-
|
|
12
|
+
date: 2022-07-18 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rake
|
|
@@ -45,14 +45,14 @@ dependencies:
|
|
|
45
45
|
requirements:
|
|
46
46
|
- - "<"
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '
|
|
48
|
+
version: '8.0'
|
|
49
49
|
type: :development
|
|
50
50
|
prerelease: false
|
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
52
|
requirements:
|
|
53
53
|
- - "<"
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: '
|
|
55
|
+
version: '8.0'
|
|
56
56
|
- !ruby/object:Gem::Dependency
|
|
57
57
|
name: rltk
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -123,6 +123,7 @@ files:
|
|
|
123
123
|
- spec/acceptance/segment_literals_spec.rb
|
|
124
124
|
- spec/acceptance/simple_expression_spec.rb
|
|
125
125
|
- spec/acceptance/subexpression_spec.rb
|
|
126
|
+
- spec/acceptance/unless_spec.rb
|
|
126
127
|
- spec/fixtures/backtrack.hbs
|
|
127
128
|
- spec/fixtures/comment.hbs
|
|
128
129
|
- spec/fixtures/custom_block_helper.hbs
|
|
@@ -134,6 +135,7 @@ files:
|
|
|
134
135
|
- spec/fixtures/raw.hbs
|
|
135
136
|
- spec/fixtures/sections.hbs
|
|
136
137
|
- spec/fixtures/simple_expression.hbs
|
|
138
|
+
- spec/fixtures/unless.hbs
|
|
137
139
|
- spec/lib/flavour_saver/lexer_spec.rb
|
|
138
140
|
- spec/lib/flavour_saver/parser_spec.rb
|
|
139
141
|
- spec/lib/flavour_saver/runtime_spec.rb
|
|
@@ -146,7 +148,7 @@ metadata:
|
|
|
146
148
|
changelog_uri: http://github.com/FlavourSaver/FlavourSaver/blob/master/CHANGELOG.md
|
|
147
149
|
homepage_uri: http://github.com/FlavourSaver/FlavourSaver
|
|
148
150
|
source_code_uri: http://github.com/FlavourSaver/FlavourSaver
|
|
149
|
-
post_install_message:
|
|
151
|
+
post_install_message:
|
|
150
152
|
rdoc_options: []
|
|
151
153
|
require_paths:
|
|
152
154
|
- lib
|
|
@@ -161,8 +163,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
161
163
|
- !ruby/object:Gem::Version
|
|
162
164
|
version: '0'
|
|
163
165
|
requirements: []
|
|
164
|
-
rubygems_version: 3.
|
|
165
|
-
signing_key:
|
|
166
|
+
rubygems_version: 3.1.6
|
|
167
|
+
signing_key:
|
|
166
168
|
specification_version: 4
|
|
167
169
|
summary: Handlebars.js without the .js
|
|
168
170
|
test_files:
|
|
@@ -181,6 +183,7 @@ test_files:
|
|
|
181
183
|
- spec/acceptance/segment_literals_spec.rb
|
|
182
184
|
- spec/acceptance/simple_expression_spec.rb
|
|
183
185
|
- spec/acceptance/subexpression_spec.rb
|
|
186
|
+
- spec/acceptance/unless_spec.rb
|
|
184
187
|
- spec/fixtures/backtrack.hbs
|
|
185
188
|
- spec/fixtures/comment.hbs
|
|
186
189
|
- spec/fixtures/custom_block_helper.hbs
|
|
@@ -192,6 +195,7 @@ test_files:
|
|
|
192
195
|
- spec/fixtures/raw.hbs
|
|
193
196
|
- spec/fixtures/sections.hbs
|
|
194
197
|
- spec/fixtures/simple_expression.hbs
|
|
198
|
+
- spec/fixtures/unless.hbs
|
|
195
199
|
- spec/lib/flavour_saver/lexer_spec.rb
|
|
196
200
|
- spec/lib/flavour_saver/parser_spec.rb
|
|
197
201
|
- spec/lib/flavour_saver/runtime_spec.rb
|