mirror of
https://github.com/kemko/liquid.git
synced 2026-01-02 08:15:41 +03:00
Compare commits
1 Commits
master
...
parse-cont
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e51931b52 |
5
.github/workflows/liquid.yml
vendored
5
.github/workflows/liquid.yml
vendored
@@ -6,8 +6,9 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
entry:
|
entry:
|
||||||
- { ruby: 2.5, allowed-failure: false } # minimum supported
|
- { ruby: 2.5, allowed-failure: false }
|
||||||
- { ruby: 3.0, allowed-failure: false } # latest
|
- { ruby: 2.6, allowed-failure: false }
|
||||||
|
- { ruby: 2.7, allowed-failure: false }
|
||||||
- { ruby: ruby-head, allowed-failure: true }
|
- { ruby: ruby-head, allowed-failure: true }
|
||||||
name: test (${{ matrix.entry.ruby }})
|
name: test (${{ matrix.entry.ruby }})
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
1022
.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml
Normal file
1022
.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml
Normal file
File diff suppressed because it is too large
Load Diff
10
.rubocop.yml
10
.rubocop.yml
@@ -1,7 +1,5 @@
|
|||||||
inherit_gem:
|
|
||||||
rubocop-shopify: rubocop.yml
|
|
||||||
|
|
||||||
inherit_from:
|
inherit_from:
|
||||||
|
- 'https://shopify.github.io/ruby-style-guide/rubocop.yml'
|
||||||
- .rubocop_todo.yml
|
- .rubocop_todo.yml
|
||||||
|
|
||||||
require: rubocop-performance
|
require: rubocop-performance
|
||||||
@@ -10,7 +8,7 @@ Performance:
|
|||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
TargetRubyVersion: 2.5
|
TargetRubyVersion: 2.4
|
||||||
NewCops: disable
|
NewCops: disable
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'vendor/bundle/**/*'
|
- 'vendor/bundle/**/*'
|
||||||
@@ -18,7 +16,3 @@ AllCops:
|
|||||||
Naming/MethodName:
|
Naming/MethodName:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'example/server/liquid_servlet.rb'
|
- 'example/server/liquid_servlet.rb'
|
||||||
|
|
||||||
# Backport https://github.com/Shopify/ruby-style-guide/pull/258
|
|
||||||
Layout/BeginEndAlignment:
|
|
||||||
Enabled: true
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
* Bugfixes
|
* Bugfixes
|
||||||
* Performance improvements
|
* Performance improvements
|
||||||
* Features that are likely to be useful to the majority of Liquid users
|
* Features that are likely to be useful to the majority of Liquid users
|
||||||
* Documentation updates that are concise and likely to be useful to the majority of Liquid users
|
|
||||||
|
|
||||||
## Things we won't merge
|
## Things we won't merge
|
||||||
|
|
||||||
@@ -15,14 +14,12 @@
|
|||||||
* Features that can easily be implemented on top of Liquid (for example as a custom filter or custom filesystem)
|
* Features that can easily be implemented on top of Liquid (for example as a custom filter or custom filesystem)
|
||||||
* Code that does not include tests
|
* Code that does not include tests
|
||||||
* Code that breaks existing tests
|
* Code that breaks existing tests
|
||||||
* Documentation changes that are verbose, incorrect or not important to most people (we want to keep it simple and easy to understand)
|
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
* [Sign the CLA](https://cla.shopify.com/) if you haven't already
|
|
||||||
* Fork the Liquid repository
|
* Fork the Liquid repository
|
||||||
* Create a new branch in your fork
|
* Create a new branch in your fork
|
||||||
* For updating [Liquid documentation](https://shopify.github.io/liquid/), create it from `gh-pages` branch. (You can skip tests.)
|
|
||||||
* If it makes sense, add tests for your code and/or run a performance benchmark
|
* If it makes sense, add tests for your code and/or run a performance benchmark
|
||||||
* Make sure all tests pass (`bundle exec rake`)
|
* Make sure all tests pass (`bundle exec rake`)
|
||||||
* Create a pull request
|
* Create a pull request
|
||||||
|
|
||||||
|
|||||||
1
Gemfile
1
Gemfile
@@ -19,7 +19,6 @@ end
|
|||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'rubocop', '~> 1.4', require: false
|
gem 'rubocop', '~> 1.4', require: false
|
||||||
gem 'rubocop-shopify', '~> 1.0.7', require: false
|
|
||||||
gem 'rubocop-performance', require: false
|
gem 'rubocop-performance', require: false
|
||||||
|
|
||||||
platform :mri, :truffleruby do
|
platform :mri, :truffleruby do
|
||||||
|
|||||||
18
History.md
18
History.md
@@ -1,23 +1,5 @@
|
|||||||
# Liquid Change Log
|
# Liquid Change Log
|
||||||
|
|
||||||
## 5.0.2 (unreleased)
|
|
||||||
|
|
||||||
### Features
|
|
||||||
* Add `base64_encode`, `base64_decode`, `base64_url_safe_encode`, and `base64_url_safe_decode` filters (#1450) [Daniel Insley]
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
* Fix support for using a String subclass for the liquid source (#1421) [Dylan Thacker-Smith]
|
|
||||||
|
|
||||||
## 5.0.1 / 2021-03-24
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
* Add ParseTreeVisitor to Echo tag (#1414) [CP Clermont]
|
|
||||||
* Test with ruby 3.0 as the latest ruby version (#1398) [Dylan Thacker-Smith]
|
|
||||||
* Handle carriage return in newlines_to_br (#1391) [Unending]
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
* Use split limit in truncatewords (#1361) [Dylan Thacker-Smith]
|
|
||||||
|
|
||||||
## 5.0.0 / 2021-01-06
|
## 5.0.0 / 2021-01-06
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ module Liquid
|
|||||||
# return this as the result.
|
# return this as the result.
|
||||||
return context.evaluate(left) if op.nil?
|
return context.evaluate(left) if op.nil?
|
||||||
|
|
||||||
left = Liquid::Utils.to_liquid_value(context.evaluate(left))
|
left = context.evaluate(left)
|
||||||
right = Liquid::Utils.to_liquid_value(context.evaluate(right))
|
right = context.evaluate(right)
|
||||||
|
|
||||||
operation = self.class.operators[op] || raise(Liquid::ArgumentError, "Unknown operator #{op}")
|
operation = self.class.operators[op] || raise(Liquid::ArgumentError, "Unknown operator #{op}")
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
require 'base64'
|
|
||||||
require 'bigdecimal'
|
require 'bigdecimal'
|
||||||
|
|
||||||
module Liquid
|
module Liquid
|
||||||
module StandardFilters
|
module StandardFilters
|
||||||
MAX_INT = (1 << 31) - 1
|
|
||||||
HTML_ESCAPE = {
|
HTML_ESCAPE = {
|
||||||
'&' => '&',
|
'&' => '&',
|
||||||
'>' => '>',
|
'>' => '>',
|
||||||
@@ -64,26 +62,6 @@ module Liquid
|
|||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def base64_encode(input)
|
|
||||||
Base64.strict_encode64(input.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def base64_decode(input)
|
|
||||||
Base64.strict_decode64(input.to_s)
|
|
||||||
rescue ::ArgumentError
|
|
||||||
raise Liquid::ArgumentError, "invalid base64 provided to base64_decode"
|
|
||||||
end
|
|
||||||
|
|
||||||
def base64_url_safe_encode(input)
|
|
||||||
Base64.urlsafe_encode64(input.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def base64_url_safe_decode(input)
|
|
||||||
Base64.urlsafe_decode64(input.to_s)
|
|
||||||
rescue ::ArgumentError
|
|
||||||
raise Liquid::ArgumentError, "invalid base64 provided to base64_url_safe_decode"
|
|
||||||
end
|
|
||||||
|
|
||||||
def slice(input, offset, length = nil)
|
def slice(input, offset, length = nil)
|
||||||
offset = Utils.to_integer(offset)
|
offset = Utils.to_integer(offset)
|
||||||
length = length ? Utils.to_integer(length) : 1
|
length = length ? Utils.to_integer(length) : 1
|
||||||
@@ -111,21 +89,13 @@ module Liquid
|
|||||||
|
|
||||||
def truncatewords(input, words = 15, truncate_string = "...")
|
def truncatewords(input, words = 15, truncate_string = "...")
|
||||||
return if input.nil?
|
return if input.nil?
|
||||||
input = input.to_s
|
wordlist = input.to_s.split
|
||||||
words = Utils.to_integer(words)
|
words = Utils.to_integer(words)
|
||||||
words = 1 if words <= 0
|
|
||||||
|
|
||||||
wordlist = begin
|
l = words - 1
|
||||||
input.split(" ", words + 1)
|
l = 0 if l < 0
|
||||||
rescue RangeError
|
|
||||||
raise if words + 1 < MAX_INT
|
|
||||||
# e.g. integer #{words} too big to convert to `int'
|
|
||||||
raise Liquid::ArgumentError, "integer #{words} too big for truncatewords"
|
|
||||||
end
|
|
||||||
return input if wordlist.length <= words
|
|
||||||
|
|
||||||
wordlist.pop
|
wordlist.length > l ? wordlist[0..l].join(" ").concat(truncate_string.to_s) : input
|
||||||
wordlist.join(" ").concat(truncate_string.to_s)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Split input string into an array of substrings separated by given pattern.
|
# Split input string into an array of substrings separated by given pattern.
|
||||||
@@ -325,7 +295,7 @@ module Liquid
|
|||||||
|
|
||||||
# Add <br /> tags in front of all newlines in input string
|
# Add <br /> tags in front of all newlines in input string
|
||||||
def newline_to_br(input)
|
def newline_to_br(input)
|
||||||
input.to_s.gsub(/\r?\n/, "<br />\n")
|
input.to_s.gsub(/\n/, "<br />\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Reformat a date using Ruby's core Time#strftime( string ) -> string
|
# Reformat a date using Ruby's core Time#strftime( string ) -> string
|
||||||
@@ -468,7 +438,7 @@ module Liquid
|
|||||||
#
|
#
|
||||||
def default(input, default_value = '', options = {})
|
def default(input, default_value = '', options = {})
|
||||||
options = {} unless options.is_a?(Hash)
|
options = {} unless options.is_a?(Hash)
|
||||||
false_check = options['allow_false'] ? input.nil? : !Liquid::Utils.to_liquid_value(input)
|
false_check = options['allow_false'] ? input.nil? : !input
|
||||||
false_check || (input.respond_to?(:empty?) && input.empty?) ? default_value : input
|
false_check || (input.respond_to?(:empty?) && input.empty?) ? default_value : input
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -52,14 +52,7 @@ module Liquid
|
|||||||
@blocks.each do |block|
|
@blocks.each do |block|
|
||||||
if block.else?
|
if block.else?
|
||||||
block.attachment.render_to_output_buffer(context, output) if execute_else_block
|
block.attachment.render_to_output_buffer(context, output) if execute_else_block
|
||||||
next
|
elsif block.evaluate(context)
|
||||||
end
|
|
||||||
|
|
||||||
result = Liquid::Utils.to_liquid_value(
|
|
||||||
block.evaluate(context)
|
|
||||||
)
|
|
||||||
|
|
||||||
if result
|
|
||||||
execute_else_block = false
|
execute_else_block = false
|
||||||
block.attachment.render_to_output_buffer(context, output)
|
block.attachment.render_to_output_buffer(context, output)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ module Liquid
|
|||||||
# {% echo user | link %}
|
# {% echo user | link %}
|
||||||
#
|
#
|
||||||
class Echo < Tag
|
class Echo < Tag
|
||||||
attr_reader :variable
|
|
||||||
|
|
||||||
def initialize(tag_name, markup, parse_context)
|
def initialize(tag_name, markup, parse_context)
|
||||||
super
|
super
|
||||||
@variable = Variable.new(markup, parse_context)
|
@variable = Variable.new(markup, parse_context)
|
||||||
@@ -22,12 +20,6 @@ module Liquid
|
|||||||
def render(context)
|
def render(context)
|
||||||
@variable.render_to_output_buffer(context, +'')
|
@variable.render_to_output_buffer(context, +'')
|
||||||
end
|
end
|
||||||
|
|
||||||
class ParseTreeVisitor < Liquid::ParseTreeVisitor
|
|
||||||
def children
|
|
||||||
[@node.variable]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Template.register_tag('echo', Echo)
|
Template.register_tag('echo', Echo)
|
||||||
|
|||||||
@@ -50,11 +50,7 @@ module Liquid
|
|||||||
|
|
||||||
def render_to_output_buffer(context, output)
|
def render_to_output_buffer(context, output)
|
||||||
@blocks.each do |block|
|
@blocks.each do |block|
|
||||||
result = Liquid::Utils.to_liquid_value(
|
if block.evaluate(context)
|
||||||
block.evaluate(context)
|
|
||||||
)
|
|
||||||
|
|
||||||
if result
|
|
||||||
return block.attachment.render_to_output_buffer(context, output)
|
return block.attachment.render_to_output_buffer(context, output)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,21 +11,13 @@ module Liquid
|
|||||||
def render_to_output_buffer(context, output)
|
def render_to_output_buffer(context, output)
|
||||||
# First condition is interpreted backwards ( if not )
|
# First condition is interpreted backwards ( if not )
|
||||||
first_block = @blocks.first
|
first_block = @blocks.first
|
||||||
result = Liquid::Utils.to_liquid_value(
|
unless first_block.evaluate(context)
|
||||||
first_block.evaluate(context)
|
|
||||||
)
|
|
||||||
|
|
||||||
unless result
|
|
||||||
return first_block.attachment.render_to_output_buffer(context, output)
|
return first_block.attachment.render_to_output_buffer(context, output)
|
||||||
end
|
end
|
||||||
|
|
||||||
# After the first condition unless works just like if
|
# After the first condition unless works just like if
|
||||||
@blocks[1..-1].each do |block|
|
@blocks[1..-1].each do |block|
|
||||||
result = Liquid::Utils.to_liquid_value(
|
if block.evaluate(context)
|
||||||
block.evaluate(context)
|
|
||||||
)
|
|
||||||
|
|
||||||
if result
|
|
||||||
return block.attachment.render_to_output_buffer(context, output)
|
return block.attachment.render_to_output_buffer(context, output)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ module Liquid
|
|||||||
attr_reader :line_number, :for_liquid_tag
|
attr_reader :line_number, :for_liquid_tag
|
||||||
|
|
||||||
def initialize(source, line_numbers = false, line_number: nil, for_liquid_tag: false)
|
def initialize(source, line_numbers = false, line_number: nil, for_liquid_tag: false)
|
||||||
@source = source.to_s.to_str
|
@source = source
|
||||||
@line_number = line_number || (line_numbers ? 1 : nil)
|
@line_number = line_number || (line_numbers ? 1 : nil)
|
||||||
@for_liquid_tag = for_liquid_tag
|
@for_liquid_tag = for_liquid_tag
|
||||||
@tokens = tokenize
|
@tokens = tokenize
|
||||||
@@ -24,7 +24,7 @@ module Liquid
|
|||||||
private
|
private
|
||||||
|
|
||||||
def tokenize
|
def tokenize
|
||||||
return [] if @source.empty?
|
return [] if @source.to_s.empty?
|
||||||
|
|
||||||
return @source.split("\n") if @for_liquid_tag
|
return @source.split("\n") if @for_liquid_tag
|
||||||
|
|
||||||
|
|||||||
@@ -81,13 +81,5 @@ module Liquid
|
|||||||
rescue ::ArgumentError
|
rescue ::ArgumentError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.to_liquid_value(obj)
|
|
||||||
# Enable "obj" to represent itself as a primitive value like integer, string, or boolean
|
|
||||||
return obj.to_liquid_value if obj.respond_to?(:to_liquid_value)
|
|
||||||
|
|
||||||
# Otherwise return the object itself
|
|
||||||
obj
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ module Liquid
|
|||||||
@lookups.each_index do |i|
|
@lookups.each_index do |i|
|
||||||
key = context.evaluate(@lookups[i])
|
key = context.evaluate(@lookups[i])
|
||||||
|
|
||||||
# Cast "key" to its liquid value to enable it to act as a primitive value
|
|
||||||
key = Liquid::Utils.to_liquid_value(key)
|
|
||||||
|
|
||||||
# If object is a hash- or array-like object we look for the
|
# If object is a hash- or array-like object we look for the
|
||||||
# presence of the key and if its available we return it
|
# presence of the key and if its available we return it
|
||||||
if object.respond_to?(:[]) &&
|
if object.respond_to?(:[]) &&
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Liquid
|
module Liquid
|
||||||
VERSION = "5.0.2.alpha"
|
VERSION = "5.0.0"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,19 +3,11 @@
|
|||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
|
||||||
module Database
|
module Database
|
||||||
DATABASE_FILE_PATH = "#{__dir__}/vision.database.yml"
|
|
||||||
|
|
||||||
# Load the standard vision toolkit database and re-arrage it to be simply exportable
|
# Load the standard vision toolkit database and re-arrage it to be simply exportable
|
||||||
# to liquid as assigns. All this is based on Shopify
|
# to liquid as assigns. All this is based on Shopify
|
||||||
def self.tables
|
def self.tables
|
||||||
@tables ||= begin
|
@tables ||= begin
|
||||||
db =
|
db = YAML.load_file("#{__dir__}/vision.database.yml")
|
||||||
if YAML.respond_to?(:unsafe_load_file) # Only Psych 4+ can use unsafe_load_file
|
|
||||||
# unsafe_load_file is needed for YAML references
|
|
||||||
YAML.unsafe_load_file(DATABASE_FILE_PATH)
|
|
||||||
else
|
|
||||||
YAML.load_file(DATABASE_FILE_PATH)
|
|
||||||
end
|
|
||||||
|
|
||||||
# From vision source
|
# From vision source
|
||||||
db['products'].each do |product|
|
db['products'].each do |product|
|
||||||
|
|||||||
@@ -73,14 +73,10 @@ class ThemeRunner
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def render_layout(template, layout, assigns)
|
|
||||||
assigns['content_for_layout'] = template.render!(assigns)
|
|
||||||
layout&.render!(assigns)
|
|
||||||
end
|
|
||||||
|
|
||||||
def compile_and_render(template, layout, assigns, page_template, template_file)
|
def compile_and_render(template, layout, assigns, page_template, template_file)
|
||||||
compiled_test = compile_test(template, layout, assigns, page_template, template_file)
|
compiled_test = compile_test(template, layout, assigns, page_template, template_file)
|
||||||
render_layout(compiled_test[:tmpl], compiled_test[:layout], compiled_test[:assigns])
|
assigns['content_for_layout'] = compiled_test[:tmpl].render!(assigns)
|
||||||
|
compiled_test[:layout].render!(assigns) if layout
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile_all_tests
|
def compile_all_tests
|
||||||
|
|||||||
@@ -461,7 +461,6 @@ class ContextTest < Minitest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_interrupt_avoids_object_allocations
|
def test_interrupt_avoids_object_allocations
|
||||||
@context.interrupt? # ruby 3.0.0 allocates on the first call
|
|
||||||
assert_no_object_allocations do
|
assert_no_object_allocations do
|
||||||
@context.interrupt?
|
@context.interrupt?
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -145,40 +145,6 @@ class StandardFiltersTest < Minitest::Test
|
|||||||
assert_equal('<strong>Hulk</strong>', @filters.escape_once('<strong>Hulk</strong>'))
|
assert_equal('<strong>Hulk</strong>', @filters.escape_once('<strong>Hulk</strong>'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_base64_encode
|
|
||||||
assert_equal('b25lIHR3byB0aHJlZQ==', @filters.base64_encode('one two three'))
|
|
||||||
assert_equal('', @filters.base64_encode(nil))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_base64_decode
|
|
||||||
assert_equal('one two three', @filters.base64_decode('b25lIHR3byB0aHJlZQ=='))
|
|
||||||
|
|
||||||
exception = assert_raises(Liquid::ArgumentError) do
|
|
||||||
@filters.base64_decode("invalidbase64")
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal('Liquid error: invalid base64 provided to base64_decode', exception.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_base64_url_safe_encode
|
|
||||||
assert_equal(
|
|
||||||
'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMTIzNDU2Nzg5MCAhQCMkJV4mKigpLT1fKy8_Ljo7W117fVx8',
|
|
||||||
@filters.base64_url_safe_encode('abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 !@#$%^&*()-=_+/?.:;[]{}\|')
|
|
||||||
)
|
|
||||||
assert_equal('', @filters.base64_url_safe_encode(nil))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_base64_url_safe_decode
|
|
||||||
assert_equal(
|
|
||||||
'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 !@#$%^&*()-=_+/?.:;[]{}\|',
|
|
||||||
@filters.base64_url_safe_decode('YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMTIzNDU2Nzg5MCAhQCMkJV4mKigpLT1fKy8_Ljo7W117fVx8')
|
|
||||||
)
|
|
||||||
exception = assert_raises(Liquid::ArgumentError) do
|
|
||||||
@filters.base64_url_safe_decode("invalidbase64")
|
|
||||||
end
|
|
||||||
assert_equal('Liquid error: invalid base64 provided to base64_url_safe_decode', exception.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_url_encode
|
def test_url_encode
|
||||||
assert_equal('foo%2B1%40example.com', @filters.url_encode('foo+1@example.com'))
|
assert_equal('foo%2B1%40example.com', @filters.url_encode('foo+1@example.com'))
|
||||||
assert_equal('1', @filters.url_encode(1))
|
assert_equal('1', @filters.url_encode(1))
|
||||||
@@ -205,17 +171,10 @@ class StandardFiltersTest < Minitest::Test
|
|||||||
assert_equal('one two three', @filters.truncatewords('one two three'))
|
assert_equal('one two three', @filters.truncatewords('one two three'))
|
||||||
assert_equal(
|
assert_equal(
|
||||||
'Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13”...',
|
'Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13”...',
|
||||||
@filters.truncatewords('Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13” x 16” x 10.5” high) with cover.', 15)
|
@filters.truncatewords('Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13” x 16” x 10.5” high) with cover.', 15)
|
||||||
)
|
)
|
||||||
assert_equal("测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5))
|
assert_equal("测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5))
|
||||||
assert_equal('one two1', @filters.truncatewords("one two three", 2, 1))
|
assert_equal('one two1', @filters.truncatewords("one two three", 2, 1))
|
||||||
assert_equal('one two three...', @filters.truncatewords("one two\tthree\nfour", 3))
|
|
||||||
assert_equal('one two...', @filters.truncatewords("one two three four", 2))
|
|
||||||
assert_equal('one...', @filters.truncatewords("one two three four", 0))
|
|
||||||
exception = assert_raises(Liquid::ArgumentError) do
|
|
||||||
@filters.truncatewords("one two three four", 1 << 31)
|
|
||||||
end
|
|
||||||
assert_equal("Liquid error: integer #{1 << 31} too big for truncatewords", exception.message)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_strip_html
|
def test_strip_html
|
||||||
@@ -580,7 +539,6 @@ class StandardFiltersTest < Minitest::Test
|
|||||||
|
|
||||||
def test_newlines_to_br
|
def test_newlines_to_br
|
||||||
assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc")
|
assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc")
|
||||||
assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\r\nb\nc")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_plus
|
def test_plus
|
||||||
@@ -728,8 +686,6 @@ class StandardFiltersTest < Minitest::Test
|
|||||||
assert_equal("bar", @filters.default([], "bar"))
|
assert_equal("bar", @filters.default([], "bar"))
|
||||||
assert_equal("bar", @filters.default({}, "bar"))
|
assert_equal("bar", @filters.default({}, "bar"))
|
||||||
assert_template_result('bar', "{{ false | default: 'bar' }}")
|
assert_template_result('bar', "{{ false | default: 'bar' }}")
|
||||||
assert_template_result('bar', "{{ drop | default: 'bar' }}", 'drop' => BooleanDrop.new(false))
|
|
||||||
assert_template_result('Yay', "{{ drop | default: 'bar' }}", 'drop' => BooleanDrop.new(true))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_default_handle_false
|
def test_default_handle_false
|
||||||
@@ -740,8 +696,6 @@ class StandardFiltersTest < Minitest::Test
|
|||||||
assert_equal("bar", @filters.default([], "bar", "allow_false" => true))
|
assert_equal("bar", @filters.default([], "bar", "allow_false" => true))
|
||||||
assert_equal("bar", @filters.default({}, "bar", "allow_false" => true))
|
assert_equal("bar", @filters.default({}, "bar", "allow_false" => true))
|
||||||
assert_template_result('false', "{{ false | default: 'bar', allow_false: true }}")
|
assert_template_result('false', "{{ false | default: 'bar', allow_false: true }}")
|
||||||
assert_template_result('Nay', "{{ drop | default: 'bar', allow_false: true }}", 'drop' => BooleanDrop.new(false))
|
|
||||||
assert_template_result('Yay', "{{ drop | default: 'bar', allow_false: true }}", 'drop' => BooleanDrop.new(true))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_cannot_access_private_methods
|
def test_cannot_access_private_methods
|
||||||
|
|||||||
@@ -96,12 +96,12 @@ class IncludeTagTest < Minitest::Test
|
|||||||
|
|
||||||
def test_include_tag_with_alias
|
def test_include_tag_with_alias
|
||||||
assert_template_result("Product: Draft 151cm ",
|
assert_template_result("Product: Draft 151cm ",
|
||||||
"{% include 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
"{% include 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_include_tag_for_alias
|
def test_include_tag_for_alias
|
||||||
assert_template_result("Product: Draft 151cm Product: Element 155cm ",
|
assert_template_result("Product: Draft 151cm Product: Element 155cm ",
|
||||||
"{% include 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
"{% include 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_include_tag_with_default_name
|
def test_include_tag_with_default_name
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert_template_result("Product: Draft 151cm ",
|
assert_template_result("Product: Draft 151cm ",
|
||||||
"{% render 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
"{% render 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_tag_with_alias
|
def test_render_tag_with_alias
|
||||||
@@ -161,7 +161,7 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert_template_result("Product: Draft 151cm ",
|
assert_template_result("Product: Draft 151cm ",
|
||||||
"{% render 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
"{% render 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_tag_for_alias
|
def test_render_tag_for_alias
|
||||||
@@ -171,7 +171,7 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert_template_result("Product: Draft 151cm Product: Element 155cm ",
|
assert_template_result("Product: Draft 151cm Product: Element 155cm ",
|
||||||
"{% render 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
"{% render 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_tag_for
|
def test_render_tag_for
|
||||||
@@ -181,7 +181,7 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert_template_result("Product: Draft 151cm Product: Element 155cm ",
|
assert_template_result("Product: Draft 151cm Product: Element 155cm ",
|
||||||
"{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
"{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_tag_forloop
|
def test_render_tag_forloop
|
||||||
@@ -190,7 +190,7 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert_template_result("Product: Draft 151cm first index:1 Product: Element 155cm last index:2 ",
|
assert_template_result("Product: Draft 151cm first index:1 Product: Element 155cm last index:2 ",
|
||||||
"{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
"{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_tag_for_drop
|
def test_render_tag_for_drop
|
||||||
@@ -199,7 +199,7 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert_template_result("123",
|
assert_template_result("123",
|
||||||
"{% render 'loop' for loop as value %}", "loop" => TestEnumerable.new)
|
"{% render 'loop' for loop as value %}", "loop" => TestEnumerable.new)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_tag_with_drop
|
def test_render_tag_with_drop
|
||||||
@@ -208,6 +208,6 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert_template_result("TestEnumerable",
|
assert_template_result("TestEnumerable",
|
||||||
"{% render 'loop' with loop as value %}", "loop" => TestEnumerable.new)
|
"{% render 'loop' with loop as value %}", "loop" => TestEnumerable.new)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -323,18 +323,4 @@ class TemplateTest < Minitest::Test
|
|||||||
result = t.render('x' => 1, 'y' => 5)
|
result = t.render('x' => 1, 'y' => 5)
|
||||||
assert_equal('12345', result)
|
assert_equal('12345', result)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_source_string_subclass
|
|
||||||
string_subclass = Class.new(String) do
|
|
||||||
# E.g. ActiveSupport::SafeBuffer does this, so don't just rely on to_s to return a String
|
|
||||||
def to_s
|
|
||||||
self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
source = string_subclass.new("{% assign x = 2 -%} x= {{- x }}")
|
|
||||||
assert_instance_of(string_subclass, source)
|
|
||||||
output = Template.parse(source).render!
|
|
||||||
assert_equal("x=2", output)
|
|
||||||
assert_instance_of(String, output)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,33 +15,6 @@ class VariableTest < Minitest::Test
|
|||||||
assert_template_result('foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new)
|
assert_template_result('foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_variable_lookup_calls_to_liquid_value
|
|
||||||
assert_template_result('1', '{{ foo }}', 'foo' => IntegerDrop.new('1'))
|
|
||||||
assert_template_result('2', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => [1, 2, 3])
|
|
||||||
assert_template_result('one', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => { 1 => 'one' })
|
|
||||||
assert_template_result('Yay', '{{ foo }}', 'foo' => BooleanDrop.new(true))
|
|
||||||
assert_template_result('YAY', '{{ foo | upcase }}', 'foo' => BooleanDrop.new(true))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_if_tag_calls_to_liquid_value
|
|
||||||
assert_template_result('one', '{% if foo == 1 %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
|
|
||||||
assert_template_result('one', '{% if 0 < foo %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
|
|
||||||
assert_template_result('one', '{% if foo > 0 %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
|
|
||||||
assert_template_result('true', '{% if foo == true %}true{% endif %}', 'foo' => BooleanDrop.new(true))
|
|
||||||
assert_template_result('true', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(true))
|
|
||||||
|
|
||||||
assert_template_result('', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(false))
|
|
||||||
assert_template_result('', '{% if foo == true %}True{% endif %}', 'foo' => BooleanDrop.new(false))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_unless_tag_calls_to_liquid_value
|
|
||||||
assert_template_result('', '{% unless foo %}true{% endunless %}', 'foo' => BooleanDrop.new(true))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_case_tag_calls_to_liquid_value
|
|
||||||
assert_template_result('One', '{% case foo %}{% when 1 %}One{% endcase %}', 'foo' => IntegerDrop.new('1'))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_simple_with_whitespaces
|
def test_simple_with_whitespaces
|
||||||
template = Template.parse(%( {{ test }} ))
|
template = Template.parse(%( {{ test }} ))
|
||||||
assert_equal(' worked ', template.render!('test' => 'worked'))
|
assert_equal(' worked ', template.render!('test' => 'worked'))
|
||||||
@@ -131,8 +104,4 @@ class VariableTest < Minitest::Test
|
|||||||
def test_dynamic_find_var
|
def test_dynamic_find_var
|
||||||
assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
|
assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_raw_value_variable
|
|
||||||
assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -119,44 +119,6 @@ class ThingWithToLiquid
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class IntegerDrop < Liquid::Drop
|
|
||||||
def initialize(value)
|
|
||||||
super()
|
|
||||||
@value = value.to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
def ==(other)
|
|
||||||
@value == other
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
@value.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_liquid_value
|
|
||||||
@value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class BooleanDrop < Liquid::Drop
|
|
||||||
def initialize(value)
|
|
||||||
super()
|
|
||||||
@value = value
|
|
||||||
end
|
|
||||||
|
|
||||||
def ==(other)
|
|
||||||
@value == other
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_liquid_value
|
|
||||||
@value
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
@value ? "Yay" : "Nay"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class ErrorDrop < Liquid::Drop
|
class ErrorDrop < Liquid::Drop
|
||||||
def standard_error
|
def standard_error
|
||||||
raise Liquid::StandardError, 'standard error'
|
raise Liquid::StandardError, 'standard error'
|
||||||
|
|||||||
@@ -26,13 +26,6 @@ class ParseTreeVisitorTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_echo
|
|
||||||
assert_equal(
|
|
||||||
["test"],
|
|
||||||
visit(%({% echo test %}))
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_if_condition
|
def test_if_condition
|
||||||
assert_equal(
|
assert_equal(
|
||||||
["test"],
|
["test"],
|
||||||
|
|||||||
Reference in New Issue
Block a user