From b0b7114c3bea301143e4c2ef58189fc15649ac6c Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Thu, 2 Feb 2023 14:50:43 +0100 Subject: [PATCH] feat: jsv support for primitives --- lib/support/jsv.rb | 9 +++ lib/support/jsv/core_ext/array.rb | 5 ++ lib/support/jsv/core_ext/false_class.rb | 5 ++ lib/support/jsv/core_ext/hash.rb | 11 ++++ lib/support/jsv/core_ext/number.rb | 5 ++ lib/support/jsv/core_ext/string.rb | 12 ++++ lib/support/jsv/core_ext/symbol.rb | 5 ++ lib/support/jsv/core_ext/true_class.rb | 5 ++ spec/lib/support/jsv_spec.rb | 75 +++++++++++++++++++++++++ 9 files changed, 132 insertions(+) create mode 100644 lib/support/jsv.rb create mode 100644 lib/support/jsv/core_ext/array.rb create mode 100644 lib/support/jsv/core_ext/false_class.rb create mode 100644 lib/support/jsv/core_ext/hash.rb create mode 100644 lib/support/jsv/core_ext/number.rb create mode 100644 lib/support/jsv/core_ext/string.rb create mode 100644 lib/support/jsv/core_ext/symbol.rb create mode 100644 lib/support/jsv/core_ext/true_class.rb create mode 100644 spec/lib/support/jsv_spec.rb diff --git a/lib/support/jsv.rb b/lib/support/jsv.rb new file mode 100644 index 000000000..0d09cf69d --- /dev/null +++ b/lib/support/jsv.rb @@ -0,0 +1,9 @@ +# spec by dolist https://api.dolist.com/ConvertJSON-to-JSV.html +# +require_relative "jsv/core_ext/array" +require_relative "jsv/core_ext/false_class" +require_relative "jsv/core_ext/hash" +require_relative "jsv/core_ext/number" +require_relative "jsv/core_ext/string" +require_relative "jsv/core_ext/symbol" +require_relative "jsv/core_ext/true_class" diff --git a/lib/support/jsv/core_ext/array.rb b/lib/support/jsv/core_ext/array.rb new file mode 100644 index 000000000..67c262513 --- /dev/null +++ b/lib/support/jsv/core_ext/array.rb @@ -0,0 +1,5 @@ +class Array + def to_jsv + "[" + reject(&:nil?).map(&:to_jsv).join(",") + "]" + end +end diff --git a/lib/support/jsv/core_ext/false_class.rb b/lib/support/jsv/core_ext/false_class.rb new file mode 100644 index 000000000..171eb991b --- /dev/null +++ b/lib/support/jsv/core_ext/false_class.rb @@ -0,0 +1,5 @@ +class TrueClass + def to_jsv + "True" + end +end diff --git a/lib/support/jsv/core_ext/hash.rb b/lib/support/jsv/core_ext/hash.rb new file mode 100644 index 000000000..3fc326552 --- /dev/null +++ b/lib/support/jsv/core_ext/hash.rb @@ -0,0 +1,11 @@ +class Hash + def to_jsv + js_array = filter_map do |key, value| + next if value.nil? # skip nil values + + "#{key.to_jsv}:#{value.to_jsv}" + end + + "{" + js_array.join(",") + "}" + end +end diff --git a/lib/support/jsv/core_ext/number.rb b/lib/support/jsv/core_ext/number.rb new file mode 100644 index 000000000..def9ee63d --- /dev/null +++ b/lib/support/jsv/core_ext/number.rb @@ -0,0 +1,5 @@ +class Numeric + def to_jsv + self + end +end diff --git a/lib/support/jsv/core_ext/string.rb b/lib/support/jsv/core_ext/string.rb new file mode 100644 index 000000000..fb1cc0a8a --- /dev/null +++ b/lib/support/jsv/core_ext/string.rb @@ -0,0 +1,12 @@ +class String + JSV_REGEX_SPECIAL_CHARS = /[\[\]\{\}"\,]/.freeze + + def to_jsv + double_quoted = self.gsub('"', '""') + if match?(JSV_REGEX_SPECIAL_CHARS) + "\"#{double_quoted}\"" + else + double_quoted + end + end +end diff --git a/lib/support/jsv/core_ext/symbol.rb b/lib/support/jsv/core_ext/symbol.rb new file mode 100644 index 000000000..44c26d6c3 --- /dev/null +++ b/lib/support/jsv/core_ext/symbol.rb @@ -0,0 +1,5 @@ +class Symbol + def to_jsv + to_s.to_jsv + end +end diff --git a/lib/support/jsv/core_ext/true_class.rb b/lib/support/jsv/core_ext/true_class.rb new file mode 100644 index 000000000..090ebe9f7 --- /dev/null +++ b/lib/support/jsv/core_ext/true_class.rb @@ -0,0 +1,5 @@ +class FalseClass + def to_jsv + "False" + end +end diff --git a/spec/lib/support/jsv_spec.rb b/spec/lib/support/jsv_spec.rb new file mode 100644 index 000000000..f3b9670d0 --- /dev/null +++ b/spec/lib/support/jsv_spec.rb @@ -0,0 +1,75 @@ +require_relative "../../../lib/support/jsv" + +describe ".to_jsv support" do + it "converts a Hash to JSV" do + expect({}.to_jsv).to eq("{}") + expect({ "a" => "b" }.to_jsv).to eq("{a:b}") + end + + it "converts an Array to JSV" do + expect([].to_jsv).to eq("[]") + expect(["a", "b"].to_jsv).to eq("[a,b]") + end + + it "converts a String to JSV" do + expect("".to_jsv).to eq("") + expect("a".to_jsv).to eq("a") + + # escape special characters + expect("a[b".to_jsv).to eq('"a[b"') + expect("a]b".to_jsv).to eq('"a]b"') + expect("a,b".to_jsv).to eq('"a,b"') + expect("a{b".to_jsv).to eq('"a{b"') + expect("a}b".to_jsv).to eq('"a}b"') + expect('a"b'.to_jsv).to eq('"a""b"') + end + + it "skip null values" do + expect({ "a" => nil }.to_jsv).to eq("{}") + expect([nil].to_jsv).to eq("[]") + end + + it "converts symbols like strings" do + expect({ a: :b }.to_jsv).to eq("{a:b}") + end + + it "converts booleans" do + expect(true.to_jsv).to eq("True") + expect(false.to_jsv).to eq("False") + end + + it "converts numbers" do + expect(1.to_jsv).to eq(1) + expect(3.14.to_jsv).to eq(3.14) + end + + it "converts nested structures" do + expect({ "a" => { "b" => "c" } }.to_jsv).to eq("{a:{b:c}}") + expect({ "a" => ["b", "c"] }.to_jsv).to eq("{a:[b,c]}") + end + + it "converts relastic structures" do + hash = { + Type: :TransactionalService, + "Contact": { + "FieldList": [ + { + "ID": 3, + "Value": "glou[0]" + } + ] + }, + "Message": { + "Subject": "You, and me", + "ForceHttp": true, + "IsTrackingValidated": false, + "IgnoreMe": nil, + "SourceCode": "

Un mail tout simple pour commencer

", + "SourceWithQuote": 'Ceci est une double quote: "' + } + } + + expected = '{Type:TransactionalService,Contact:{FieldList:[{ID:3,Value:"glou[0]"}]},Message:{Subject:"You, and me",ForceHttp:True,IsTrackingValidated:False,SourceCode:

Un mail tout simple pour commencer

,SourceWithQuote:"Ceci est une double quote: """}}' + expect(hash.to_jsv).to eq(expected) + end +end