From 3130c704afa0a163395bbf5279b69d8da42a5b8d Mon Sep 17 00:00:00 2001 From: Jakob Skjerning Date: Mon, 8 Dec 2025 14:38:52 +0100 Subject: [PATCH 1/3] Make it possible to run the test in isolation Without this we'd get ``` $ ruby -Itest test/classlist/test_operation.rb Run options: --seed 53158 ..EE........E... Finished in 0.010779s, 1391.5948 runs/s, 1298.8218 assertions/s. 1) Error: TestClasslistOperation#test_all_the_operations: NameError: uninitialized constant Classlist::Reset test/classlist/test_operation.rb:97:in 'TestClasslistOperation#test_all_the_operations' 2) Error: TestClasslistOperation#test_reset_as_manual_operations: NameError: uninitialized constant Classlist::Reset test/classlist/test_operation.rb:41:in 'TestClasslistOperation#test_reset_as_manual_operations' 3) Error: TestClasslistOperation#test_reset: NameError: uninitialized constant Classlist::Reset test/classlist/test_operation.rb:35:in 'TestClasslistOperation#test_reset' ``` --- test/classlist/test_operation.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/classlist/test_operation.rb b/test/classlist/test_operation.rb index 546bb86..21970f4 100644 --- a/test/classlist/test_operation.rb +++ b/test/classlist/test_operation.rb @@ -4,6 +4,7 @@ require "classlist/add" require "classlist/remove" +require "classlist/reset" class TestClasslistOperation < Minitest::Test def test_add From 3892e86c5fc5345ab408035dae6c4236839742b0 Mon Sep 17 00:00:00 2001 From: Jakob Skjerning Date: Mon, 8 Dec 2025 15:11:13 +0100 Subject: [PATCH 2/3] Assume adding a Classlist is an Add operation Ie doing Classlist.new("a b c") + Classlist.new("d e") is the same as Classlist.new("a b c") + Classlist::Add.new("d e") and most notably doing Classlist.new("a") + Classlist::Remove.new("a") + Classlist.new("b") is the same as Classlist.new("a") + Classlist::Remove.new("a") + Classlist::Add.new("b") which it wasn't before. Adding a "base" Classlist in that manner would merge it into the Remove operation, effectively turning the statement into Classlist.new("a") + Classlist::Remove.new("a b") which is not the intended behavior --- CHANGELOG.md | 4 ++++ lib/classlist.rb | 5 +++++ test/classlist/test_operation.rb | 16 ++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9ef493..655b067 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Code of Conduct. - Add support for Ruby 3.2 and 3.3 (no changes). +### Fixed + +- Adding a raw `Classlist` to a set of `Classlist::Operation`s would merge the `Classlist` into the last operation, instead of treating the `Classlist` as an implicit `Classlist::Add` operation (which it should be). + ## [1.1.0] - 2022-11-07 ### Added diff --git a/lib/classlist.rb b/lib/classlist.rb index d2428f5..ffc23d2 100644 --- a/lib/classlist.rb +++ b/lib/classlist.rb @@ -16,6 +16,11 @@ class Error < StandardError; end # Returns the Classlist resulting from adding other to this classlist. def +(other) + # When adding a basic Classlist to an existing list, assume an Add operation + if other.is_a?(Classlist) && !other.is_a?(Classlist::Operation) + other = Classlist::Add.new(other.entries.dup) + end + case other when Classlist::Operation add_operation(other) diff --git a/test/classlist/test_operation.rb b/test/classlist/test_operation.rb index 21970f4..a57152b 100644 --- a/test/classlist/test_operation.rb +++ b/test/classlist/test_operation.rb @@ -93,6 +93,22 @@ def test_storing_operations_in_a_variable assert_equal(["this"], result.to_a) end + def test_adding_after_removing + base = Classlist.new("foo") + removal = Classlist::Remove.new("foo") + addition = Classlist::Add.new("addition") + result = base + removal + addition + assert_equal(["addition"], result.to_a) + end + + def test_adding_a_classlist_instance_assumes_add + base = Classlist.new("foo") + removal = Classlist::Remove.new("foo") + addition = Classlist.new("addition") + result = base + removal + addition + assert_equal(["addition"], result.to_a) + end + def test_all_the_operations result = Classlist.new("start") + Classlist::Reset.new("with") + From 2e6610076a0e1f68e6e537b5f784c95f29fc17a1 Mon Sep 17 00:00:00 2001 From: Jakob Skjerning Date: Mon, 8 Dec 2025 15:15:52 +0100 Subject: [PATCH 3/3] Appease standard > lib/classlist.rb:12:3: Layout/EmptyLinesAfterModuleInclusion: Add an > empty line after module inclusion. --- lib/classlist.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/classlist.rb b/lib/classlist.rb index ffc23d2..dedc0c4 100644 --- a/lib/classlist.rb +++ b/lib/classlist.rb @@ -10,6 +10,7 @@ class ArgumentError < ::ArgumentError; end class Error < StandardError; end extend Forwardable + def_delegators :@entries, :each attr_reader :entries, :operations