Skip to content

Commit 549d893

Browse files
committed
add json options for speed
1 parent a79cde6 commit 549d893

File tree

3 files changed

+110
-1
lines changed

3 files changed

+110
-1
lines changed

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ Style/ArgumentsForwarding:
3838
Style/SymbolArray:
3939
EnforcedStyle: percent
4040

41+
RSpec/NestedGroups:
42+
Max: 4
43+
4144
Layout/LineLength:
4245
Max: 120
4346
AllowedPatterns: ['^ *# '] # allow longer comments

lib/json_mend.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ class << self
1616
def repair(json_string, return_objects: false)
1717
# First, attempt to parse the string with the standard library.
1818
repaired_json = begin
19-
JSON.parse(json_string)
19+
JSON.parse(
20+
json_string,
21+
allow_trailing_comma: true,
22+
allow_control_characters: true
23+
)
2024
rescue JSON::ParserError
2125
parser = Parser.new(json_string)
2226
parser.parse

spec/json_mend/parser_spec.rb

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe JsonMend::Parser do
4+
describe '#parse' do
5+
subject { parser.parse }
6+
7+
let(:parser) { described_class.new(input) }
8+
9+
# Requirement: Allow // and /**/ comments
10+
context 'with comments' do
11+
context 'with single-line // comments' do
12+
let(:input) do
13+
<<~JSON
14+
{
15+
"key": "value" // This is a comment
16+
}
17+
JSON
18+
end
19+
20+
it { is_expected.to eq({ 'key' => 'value' }) }
21+
end
22+
23+
context 'with inline /* */ comments' do
24+
let(:input) { '{ "key": /* comment */ "value" }' }
25+
26+
it { is_expected.to eq({ 'key' => 'value' }) }
27+
end
28+
29+
context 'with multi-line /* */ comments' do
30+
let(:input) do
31+
<<~JSON
32+
{
33+
"key": "value" /* multi-line
34+
comment
35+
*/
36+
}
37+
JSON
38+
end
39+
40+
it { is_expected.to eq({ 'key' => 'value' }) }
41+
end
42+
end
43+
44+
# Requirement: Allow unescaped newlines
45+
context 'with unescaped control characters' do
46+
context 'with literal newlines' do
47+
let(:input) do
48+
<<~JSON
49+
{
50+
"description": "Line 1
51+
Line 2"
52+
}
53+
JSON
54+
end
55+
let(:expected_output) { { 'description' => "Line 1\nLine 2" } }
56+
57+
it { is_expected.to eq(expected_output) }
58+
end
59+
60+
context 'with literal tabs' do
61+
let(:input) { "{\"key\": \"value\twith\ttab\"}" }
62+
let(:expected_output) { { 'key' => "value\twith\ttab" } }
63+
64+
it { is_expected.to eq(expected_output) }
65+
end
66+
end
67+
68+
# Requirement: Allow trailing commas
69+
context 'with trailing commas' do
70+
context 'when in objects' do
71+
let(:input) do
72+
<<~JSON
73+
{
74+
"a": 1,
75+
"b": 2,
76+
}
77+
JSON
78+
end
79+
80+
it { is_expected.to eq({ 'a' => 1, 'b' => 2 }) }
81+
end
82+
83+
context 'when in arrays' do
84+
let(:input) { '[1, 2, 3, ]' }
85+
86+
it { is_expected.to eq([1, 2, 3]) }
87+
end
88+
89+
context 'when mixed with comments' do
90+
let(:input) do
91+
<<~JSON
92+
{
93+
"a": 1, // comment
94+
}
95+
JSON
96+
end
97+
98+
it { is_expected.to eq({ 'a' => 1 }) }
99+
end
100+
end
101+
end
102+
end

0 commit comments

Comments
 (0)