From 95d375629af90ffc62b970a1f35b5bf10669e9ba Mon Sep 17 00:00:00 2001 From: jules-w2 Date: Mon, 7 Sep 2026 12:41:16 -0500 Subject: [PATCH] Allow comments when reading the JSON cache files `Measured::Cache::JsonWriter` prefixes every cache file it writes with a `// Do not modify this file directly.` line, which is not valid JSON. `Measured::Cache::Json#read` relied on the json gem accepting JavaScript comments by default. json 3.0 turned that off: `allow_comments` now defaults to `false`, so requiring `measured` raises JSON::ParserError: unexpected token '//' at line 1 column 1 while loading `cache/length.json`, and the gem cannot be loaded at all. Under Bundler this surfaces as a `Bundler::GemRequireError` at boot. Opt back into comments when reading the cache. The option was introduced in json 2.20 and is silently ignored by older versions, which accept comments anyway, so this stays compatible with every json version supported by the gem. The existing `#read` test passes a payload without the comment header, which is why the suite did not catch this; add a test that uses the exact header `JsonWriter` produces. --- CHANGELOG.md | 1 + lib/measured/cache/json.rb | 5 ++++- test/cache/json_test.rb | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7d4a3a..24a9a00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ Unreleased ----- +* Fix loading the JSON conversion table cache under json 3.0, which no longer accepts comments by default. (@jules-w2) 3.2.1 ----- diff --git a/lib/measured/cache/json.rb b/lib/measured/cache/json.rb index 080464f..24bc1ee 100644 --- a/lib/measured/cache/json.rb +++ b/lib/measured/cache/json.rb @@ -15,7 +15,10 @@ def exist? def read return unless exist? - decode(JSON.load(File.read(@path), nil, freeze: true)) + # The cache files written by Measured::Cache::JsonWriter start with a `//` comment line, which is not + # valid JSON. json < 3.0 accepted comments by default, json >= 3.0 requires opting in. The option is + # ignored by json < 2.20, where comments are accepted anyway. + decode(JSON.load(File.read(@path), nil, freeze: true, allow_comments: true)) end def write(table) diff --git a/test/cache/json_test.rb b/test/cache/json_test.rb index 312de07..f3f1a33 100644 --- a/test/cache/json_test.rb +++ b/test/cache/json_test.rb @@ -53,6 +53,13 @@ class Measured::Cache::JsonTest < ActiveSupport::TestCase assert_equal @table_hash, @cache.read end + test "#read loads a file that starts with the comment header written by the writer" do + commented_json = "// Do not modify this file directly. Regenerate it with 'rake cache:write'.\n#{@table_json}" + File.expects(:exist?).with(@cache.path).returns(true) + File.expects(:read).with(@cache.path).returns(commented_json) + assert_equal @table_hash, @cache.read + end + test "#write raises not implemented" do assert_raises(ArgumentError) do @cache.write({})