From 796e9f7786613ec9e765c69c7db06decf989327d Mon Sep 17 00:00:00 2001 From: Fabio Perrella Date: Wed, 8 Jul 2020 17:57:40 -0300 Subject: [PATCH] Change #as_json adding the option stringify_keys to it --- CHANGELOG.md | 3 +++ README.md | 13 ++++++++++++- lib/attributes_json.rb | 8 +++++++- lib/format_parser/version.rb | 2 +- spec/attributes_json_spec.rb | 20 ++++++++++++++++++++ spec/parsers/mp3_parser_spec.rb | 28 ++++++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 350ab89e..4c1f65b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.22.0 +* Adds option `stringify_keys: true` to #as_json methods (fix #151) + ## 0.21.1 * MPEG: Ensure parsing does not inadvertently return an Integer instead of Result|nil * MPEG: Scan further into the MPEG file than previously (scan 32 1KB chunks) diff --git a/README.md b/README.md index 980b4787..d7a8bbae 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,17 @@ img_info = FormatParser.parse(File.open("myimage.jpg", "rb")) JSON.pretty_generate(img_info) #=> ... ``` +To convert the result to a Hash + +```ruby +img_info = FormatParser.parse(File.open("myimage.jpg", "rb")) +img_info.as_json + +# it's also possible to convert all keys to string (since version 0.22) +img_info.as_json(stringify_keys: true) +``` + + ## Creating your own parsers See the [section on writing parsers in CONTRIBUTING.md](CONTRIBUTING.md#so-you-want-to-contribute-a-new-parser) @@ -188,7 +199,7 @@ Unless specified otherwise in this section the fixture files are MIT licensed an ## Copyright -Copyright (c) 2019 WeTransfer. +Copyright (c) 2020 WeTransfer. `format_parser` is distributed under the conditions of the [Hippocratic License](https://firstdonoharm.dev/version/1/2/license.html) - See LICENSE.txt for further details. diff --git a/lib/attributes_json.rb b/lib/attributes_json.rb index b2bd9d79..66779745 100644 --- a/lib/attributes_json.rb +++ b/lib/attributes_json.rb @@ -15,7 +15,10 @@ module FormatParser::AttributesJSON # Implements a sane default `as_json` for an object # that accessors defined - def as_json(root: false) + # + # stringify_keys: transforms all the hash keys to a string when is true. The + # default value is false for backward compatibility + def as_json(root: false, stringify_keys: false) h = {} h['nature'] = nature if respond_to?(:nature) # Needed for file info structs methods.grep(/\w\=$/).each_with_object(h) do |attr_writer_method_name, h| @@ -27,6 +30,9 @@ def as_json(root: false) sanitized_value = _sanitize_json_value(unwrapped_attribute_value) h[reader_method_name] = sanitized_value end + + h = FormatParser::HashUtils.deep_transform_keys(h, &:to_s) if stringify_keys + if root {'format_parser_file_info' => h} else diff --git a/lib/format_parser/version.rb b/lib/format_parser/version.rb index 58f3a9ad..1a6d4955 100644 --- a/lib/format_parser/version.rb +++ b/lib/format_parser/version.rb @@ -1,3 +1,3 @@ module FormatParser - VERSION = '0.21.1' + VERSION = '0.22.0' end diff --git a/spec/attributes_json_spec.rb b/spec/attributes_json_spec.rb index 326ac2f8..5e399813 100644 --- a/spec/attributes_json_spec.rb +++ b/spec/attributes_json_spec.rb @@ -140,4 +140,24 @@ def nature JSON.pretty_generate(object_with_attributes_module) }.to raise_error(/structure too deep/) end + + it 'converts all hash keys to string when stringify_keys: true' do + fixture_path = fixtures_dir + '/ZIP/arch_many_entries.zip' + fi_io = File.open(fixture_path, 'rb') + + result = FormatParser::ZIPParser.new.call(fi_io).as_json(stringify_keys: true) + expect( + result['entries'].flat_map { |entry| entry.keys.map(&:class) }.uniq + ).to eq([String]) + end + + it 'does not convert hash keys to string when stringify_keys: false' do + fixture_path = fixtures_dir + '/ZIP/arch_many_entries.zip' + fi_io = File.open(fixture_path, 'rb') + + result = FormatParser::ZIPParser.new.call(fi_io).as_json + expect( + result['entries'].flat_map { |entry| entry.keys.map(&:class) }.uniq + ).to eq([Symbol]) + end end diff --git a/spec/parsers/mp3_parser_spec.rb b/spec/parsers/mp3_parser_spec.rb index 2441944b..6246f381 100644 --- a/spec/parsers/mp3_parser_spec.rb +++ b/spec/parsers/mp3_parser_spec.rb @@ -110,4 +110,32 @@ subject.call(StringIO.new('')) }.to raise_error(FormatParser::IOUtils::InvalidRead) end + + describe '#as_json' do + it 'converts all hash keys to string when stringify_keys: true' do + fpath = fixtures_dir + '/MP3/Cassy.mp3' + result = subject.call(File.open(fpath, 'rb')).as_json(stringify_keys: true) + + expect( + result['intrinsics'].keys.map(&:class).uniq + ).to eq([String]) + + expect( + result['intrinsics']['id3tags'].map(&:class).uniq + ).to eq([ID3Tag::Tag]) + end + + it 'does not convert the hash keys to string when stringify_keys: false' do + fpath = fixtures_dir + '/MP3/Cassy.mp3' + result = subject.call(File.open(fpath, 'rb')).as_json + + expect( + result['intrinsics'].keys.map(&:class).uniq + ).to eq([Symbol]) + + expect( + result['intrinsics'][:id3tags].map(&:class).uniq + ).to eq([ID3Tag::Tag]) + end + end end