Added Liquid utilities patch for string and object inspection

As mentioned in 2fe0094 (Updated to SimpleCov 1.0.0), Liquid violates the _Liskov Substitution Principle_ due to expecting an object to be passed to both the `#inspect` and `#to_s` methods which breaks the `Object` (superclass) contract. Doesn't help that Liquid doesn't even try to be a good citizen when it comes to link:https://alchemists.io/articles/ruby_object_inspection[Ruby Object Inspection] in general.

The following takes this a step further by monkey patching `Liquid::Utils` (yes, this is ugly but is the best we can do until Liquid patches their implementation). The specs were updated to account for this since Liquid also doesn't bother to properly format hashes when inspected like Ruby does by default.

All of this work means that we can finally build SimpleCov reports in CI. Again, none of this happens when running locally on macOS. This only crops up in CI.

Milestone: patch
This commit is contained in:
Brooke Kuhlmann
2026-07-18 11:13:41 -06:00
parent fc488f7caf
commit 559387e2e8
3 changed files with 15 additions and 11 deletions
+11
View File
@@ -5,6 +5,16 @@ require "trmnl/liquid/filters"
require "trmnl/liquid/memory_system"
require "trmnl/liquid/template_tag"
# rubocop:todo Style/OneClassPerFile
module Liquid
# TODO: Remove once Liquid is patched. Broken since Liquid 5.13.0. Issue: 2107.
module Utils
def self.inspect(object = nil, seen = {}) = seen.empty? ? object.to_s : super
def self.to_s(object = nil, seen = {}) = seen.empty? ? object.to_s : super
end
end
module TRMNL
# Main namespace.
module Liquid
@@ -32,3 +42,4 @@ module TRMNL
end
end
end
# rubocop:enable Style/OneClassPerFile
-7
View File
@@ -8,13 +8,6 @@ unless ENV["COVERAGE"] == "no"
end
end
# TODO: Remove once the Liquid gem is fixed because it violates Object#inspect behavior.
SimpleCov.at_exit do
SimpleCov.result.format!
rescue ArgumentError => error
warn "Liquid object inspection failure: #{error.message}"
end
Bundler.require :tools
require "refinements"
+4 -4
View File
@@ -57,8 +57,8 @@ RSpec.describe TRMNL::Liquid::Filters do
}
expect(content).to eq(
%({35=>[{"name"=>"Ryan", "age"=>35}], 29=>[{"name"=>"Sara", "age"=>29}, ) +
%({"name"=>"Jimbob", "age"=>29}]})
%({35 => [{"name" => "Ryan", "age" => 35}], 29 => [{"name" => "Sara", "age" => 29}, ) +
%({"name" => "Jimbob", "age" => 29}]})
)
end
end
@@ -84,7 +84,7 @@ RSpec.describe TRMNL::Liquid::Filters do
it "finds by name" do
content = renderer.call "{{ collection | find_by: 'name', 'Ryan' }}",
{"collection" => collection}
expect(content).to eq('{"name"=>"Ryan", "age"=>35}')
expect(content).to eq('{"name" => "Ryan", "age" => 35}')
end
it "answers fallback when not found" do
@@ -293,7 +293,7 @@ RSpec.describe TRMNL::Liquid::Filters do
data = {"towns" => [{"id" => 1, "label" => "Boulder"}, {"id" => 2, "label" => "Bozeman"}]}
content = renderer.call template, data
expect(content.strip).to eq(%({"id"=>1, "label"=>"Boulder"}))
expect(content.strip).to eq(%({"id" => 1, "label" => "Boulder"}))
end
it "answers content which matches equation" do