diff --git a/.github/workflows/ci_jruby.yml b/.github/workflows/ci_jruby.yml index aead15d9..5629d11d 100644 --- a/.github/workflows/ci_jruby.yml +++ b/.github/workflows/ci_jruby.yml @@ -17,3 +17,5 @@ jobs: ruby-version: ${{ matrix.ruby }} bundler-cache: true - run: bundle exec rake + env: + JRUBY_OPTS: --profile diff --git a/.gitignore b/.gitignore index d51937d8..6cb20958 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ Gemfile.lock *.swp *.swo bin +# Jetbrains IDEs +.idea +*.iml +/out diff --git a/Gemfile b/Gemfile index da67af7d..9bbf93d7 100644 --- a/Gemfile +++ b/Gemfile @@ -7,5 +7,5 @@ group :test do gem "multi_json", require: false gem "nokogiri", require: false end -gem 'pry-byebug' +gem 'pry-byebug', platform: :mri diff --git a/test/as_test.rb b/test/as_test.rb index 1040d19a..bc95badb 100644 --- a/test/as_test.rb +++ b/test/as_test.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + require "test_helper" class AsTest < MiniTest::Spec for_formats( - :hash => [Representable::Hash, {"title" => "Wie Es Geht"}, {"title" => "Revolution"}] + hash: [Representable::Hash, {"title" => "Wie Es Geht"}, {"title" => "Revolution"}] # :xml => [Representable::XML, "\n \n Alive\n \n", "You've Taken Everything/open_struct>"], # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"], ) do |format, mod, input, output| @@ -10,30 +12,32 @@ class AsTest < MiniTest::Spec let(:format) { format } describe "as: with :symbol" do - representer!(:module => mod) do - property :name, :as => :title + representer!(module: mod) do + property :name, as: :title end - it { render(song).must_equal_document output } + it { assert_equal_document render(song), output } it { _(parse(song, input).name).must_equal "Wie Es Geht" } end describe "as: with lambda" do - representer!(:module => mod) do - property :name, :as => ->(*) { self.class.to_s } + representer!(module: mod) do + property :name, as: ->(*) { self.class.to_s } end - it { render(song).must_equal_document({"Song" => "Revolution"}) } + it { assert_equal_document(render(song), {"Song" => "Revolution"}) } it { _(parse(song, {"Song" => "Wie Es Geht"}).name).must_equal "Wie Es Geht" } end describe "lambda arguments" do representer! do - property :name, :as => ->(options) { options[:user_options].inspect } + property :name, as: ->(options) { options[:user_options].inspect } end - it { render(song, user_options: {volume: 1}).must_equal_document({"{:volume=>1}" => "Revolution"}) } - it { _(parse(song, {"{:volume=>1}" => "Wie Es Geht"}, user_options: {volume: 1}).name).must_equal "Wie Es Geht" } + it { assert_equal_document(render(song, user_options: {volume: 1}), {"{:volume=>1}" => "Revolution"}) } + it { + _(parse(song, {"{:volume=>1}" => "Wie Es Geht"}, user_options: {volume: 1}).name).must_equal "Wie Es Geht" + } end end end @@ -54,7 +58,10 @@ class AsXmlTest < MiniTest::Spec end it do - skip - _(representer.new(Album.new(Band.new("Offspring"))).to_xml).must_equal "" + assert_xml_equal " + + Offspring + +", representer.new(Album.new(Band.new("Offspring"))).to_xml end end diff --git a/test/benchmarking.rb b/test/benchmarking.rb index 3f05d329..e4464963 100644 --- a/test/benchmarking.rb +++ b/test/benchmarking.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + require "test_helper" require "benchmark" -SONG_PROPERTIES = 1000.times.collect do |i| +SONG_PROPERTIES = Array.new(1000) do |i| "property_#{i}" end @@ -25,14 +27,14 @@ module AlbumRepresenter end def random_song - attrs = Hash[SONG_PROPERTIES.collect { |n| [n, n] }] + attrs = SONG_PROPERTIES.to_h { |n| [n, n] } OpenStruct.new(attrs) end times = [] 3.times.each do - album = OpenStruct.new(songs: 100.times.collect { random_song }) + album = OpenStruct.new(songs: Array.new(100) { random_song }) times << Benchmark.measure do puts "================ next!" @@ -40,7 +42,7 @@ def random_song end end -puts times.join("") +puts times.join # 100 songs, 100 attrs # 0.050000 0.000000 0.050000 ( 0.093157) diff --git a/test/binding_test.rb b/test/binding_test.rb index ac46d4d9..538a0d28 100644 --- a/test/binding_test.rb +++ b/test/binding_test.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + require "test_helper" class BindingTest < MiniTest::Spec Binding = Representable::Binding - let(:render_nil_definition) { Representable::Definition.new(:song, :render_nil => true) } + let(:render_nil_definition) { Representable::Definition.new(:song, render_nil: true) } describe "#skipable_empty_value?" do let(:binding) { Binding.new(render_nil_definition) } @@ -21,7 +23,7 @@ class BindingTest < MiniTest::Spec end describe "#default_for" do - let(:definition) { Representable::Definition.new(:song, :default => "Insider") } + let(:definition) { Representable::Definition.new(:song, default: "Insider") } let(:binding) { Binding.new(definition) } # return value when value present. @@ -41,8 +43,8 @@ class BindingTest < MiniTest::Spec _( Binding.new( Representable::Definition.new( - :song, :render_nil => true, - :default => "The Quest" + :song, render_nil: true, + default: "The Quest" ) ).default_for(nil) ).must_be_nil diff --git a/test/cached_test.rb b/test/cached_test.rb index 569da5f8..46263b33 100644 --- a/test/cached_test.rb +++ b/test/cached_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class Profiler @@ -54,8 +56,8 @@ class AlbumRepresenter < Representable::Decorator describe "serialization" do let(:album_hash) do { - "name" => "Louder And Even More Dangerous", - "songs" => [{"title"=>"Southbound:{:volume=>10}"}, {"title"=>"Jailbreak:{:volume=>10}"}] + "name" => "Louder And Even More Dangerous", + "songs" => [{"title" => "Southbound:{:volume=>10}"}, {"title" => "Jailbreak:{:volume=>10}"}] } end @@ -70,10 +72,10 @@ class AlbumRepresenter < Representable::Decorator # makes sure options are passed correctly. _(representer.to_hash(user_options: {volume: 9})).must_equal( { - "name" => "Live And Dangerous", + "name" => "Live And Dangerous", "songs" => [ - {"title"=>"Jailbreak:{:volume=>9}"}, {"title"=>"Southbound:{:volume=>9}"}, - {"title"=>"Emerald:{:volume=>9}"} + {"title" => "Jailbreak:{:volume=>9}"}, {"title" => "Southbound:{:volume=>9}"}, + {"title" => "Emerald:{:volume=>9}"} ] } ) # called in Deserializer/Serializer @@ -87,6 +89,7 @@ class AlbumRepresenter < Representable::Decorator # profiling it do + skip("TruffleRuby profiler is not implemented yet") if RUBY_ENGINE == "truffleruby" representer.to_hash data = Profiler.profile { representer.to_hash } @@ -114,11 +117,11 @@ class AlbumRepresenter < Representable::Decorator describe "deserialization" do let(:album_hash) do { - "name" => "Louder And Even More Dangerous", + "name" => "Louder And Even More Dangerous", "songs" => [ - {"title" => "Southbound", "composer" => {"name"=>"Lynott"}}, - {"title" => "Jailbreak", "composer" => {"name"=>"Phil Lynott"}}, - {"title"=>"Emerald"} + {"title" => "Southbound", "composer" => {"name" => "Lynott"}}, + {"title" => "Jailbreak", "composer" => {"name" => "Phil Lynott"}}, + {"title" => "Emerald"} ] } end @@ -141,6 +144,7 @@ class AlbumRepresenter < Representable::Decorator end it "xxx" do + skip("TruffleRuby profiler is not implemented yet") if RUBY_ENGINE == "truffleruby" representer = AlbumRepresenter.new(Model::Album.new) representer.from_hash(album_hash) diff --git a/test/class_test.rb b/test/class_test.rb index 48728d82..2e27eaec 100644 --- a/test/class_test.rb +++ b/test/class_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class ClassTest < BaseTest @@ -13,7 +15,7 @@ def from_hash(doc, *) describe "class: ClassName, only" do representer! do - property :song, :class => RepresentingSong # supposed this class exposes #from_hash itself. + property :song, class: RepresentingSong # supposed this class exposes #from_hash itself. end it "creates fresh instance and doesn't extend" do @@ -25,7 +27,7 @@ def from_hash(doc, *) describe "class: lambda, only" do representer! do - property :song, :class => ->(*) { RepresentingSong } + property :song, class: ->(*) { RepresentingSong } end it "creates fresh instance and doesn't extend" do @@ -38,7 +40,7 @@ def from_hash(doc, *) # this throws a DeserializationError now. describe "lambda { nil }" do representer! do - property :title, :class => nil + property :title, class: nil end it do @@ -61,9 +63,12 @@ def from_hash(*) end end - representer!(:inject => :klass) do + representer!(inject: :klass) do _klass = klass - property :song, :class => ->(options) { _klass.args = ([options[:fragment], options[:user_options]]); _klass } + property :song, class: ->(options) { + _klass.args = ([options[:fragment], options[:user_options]]) + _klass + } end it { @@ -73,7 +78,7 @@ def from_hash(*) user_options: {volume: true} ).song.class.args ) - .must_equal([{"name"=>"Captured"}, {:volume=>true}]) + .must_equal([{"name" => "Captured"}, {volume: true}]) } end @@ -90,10 +95,11 @@ def from_hash(*) end end - representer!(:inject => :klass) do + representer!(inject: :klass) do _klass = klass collection :songs, class: ->(options) { - _klass.args = ([options[:fragment], options[:index], options[:user_options]]); _klass + _klass.args = ([options[:fragment], options[:index], options[:user_options]]) + _klass } end @@ -104,7 +110,7 @@ def from_hash(*) user_options: {volume: true} ).songs.first.class.args ) - .must_equal([{"name"=>"Captured"}, 0, {:volume=>true}]) + .must_equal([{"name" => "Captured"}, 0, {volume: true}]) } end @@ -117,8 +123,8 @@ def from_hash(*) end end - representer!(:inject => :parser) do - property :song, :class => parser # supposed this class exposes #from_hash itself. + representer!(inject: :parser) do + property :song, class: parser # supposed this class exposes #from_hash itself. end it "allows returning arbitrary objects in #from_hash" do diff --git a/test/coercion_test.rb b/test/coercion_test.rb index bdb36c7d..4b08dbfd 100644 --- a/test/coercion_test.rb +++ b/test/coercion_test.rb @@ -30,10 +30,10 @@ class CoercionTest < MiniTest::Spec it do _(album.extend(representer).to_hash).must_equal( { - "title" => "Dire Straits", + "title" => "Dire Straits", "length" => 41.34, - "band" => {"founded" => 1977}, - "songs" => [{"ok" => true}, {"ok" => false}] + "band" => {"founded" => 1977}, + "songs" => [{"ok" => true}, {"ok" => false}] } ) end @@ -43,10 +43,10 @@ class CoercionTest < MiniTest::Spec album.extend(representer) album.from_hash( { - "title" => "Dire Straits", + "title" => "Dire Straits", "length" => "41.34", - "band" => {"founded" => "1977"}, - "songs" => [{"ok" => 1}, {"ok" => 0}] + "band" => {"founded" => "1977"}, + "songs" => [{"ok" => 1}, {"ok" => 0}] } ) @@ -60,8 +60,8 @@ class CoercionTest < MiniTest::Spec representer! do include Representable::Coercion - property :length, type: Representable::Coercion::Types::Params::Float, - parse_filter: ->(input, _options) { "#{input}.1" }, # happens BEFORE coercer. + property :length, type: Representable::Coercion::Types::Params::Float, + parse_filter: ->(input, _options) { "#{input}.1" }, # happens BEFORE coercer. render_filter: ->(fragment, *) { "#{fragment}.1" } end diff --git a/test/config/inherit_test.rb b/test/config/inherit_test.rb index 173a4661..3c69e9ae 100644 --- a/test/config/inherit_test.rb +++ b/test/config/inherit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" # tests defining representers in modules, decorators and classes and the inheritance when combined. @@ -7,7 +9,7 @@ def assert_cloned(child, parent, property) child_def = child.representable_attrs.get(property) parent_def = parent.representable_attrs.get(property) - child_def.merge!(:alias => property) + child_def.merge!(alias: property) _(child_def[:alias]).wont_equal parent_def[:alias] _(child_def.object_id).wont_equal parent_def.object_id @@ -38,6 +40,7 @@ class InheritingDecorator < Decorator end it { _(InheritingDecorator.definitions.keys).must_equal %w[title artist location] } + it { assert_cloned(InheritingDecorator, Decorator, "title") } it do _(InheritingDecorator.representable_attrs.get(:artist).representer_module.object_id).wont_equal Decorator.representable_attrs.get(:artist).representer_module.object_id @@ -51,6 +54,7 @@ class InheritingAndIncludingDecorator < Decorator end it { _(InheritingAndIncludingDecorator.definitions.keys).must_equal %w[title artist genre location] } + it { assert_cloned(InheritingAndIncludingDecorator, GenreModule, :genre) } # in module --------------------------------------------------- @@ -70,6 +74,7 @@ module SubModule end it { _(SubModule.definitions.keys).must_equal %w[title location] } + it { assert_cloned(SubModule, Module, :title) } # including preserves order @@ -90,6 +95,7 @@ class Class end it { _(Class.definitions.keys).must_equal %w[genre title location] } + it { assert_cloned(Class, IncludingModule, :title) } it { assert_cloned(Class, IncludingModule, :location) } it { assert_cloned(Class, IncludingModule, :genre) } @@ -118,6 +124,7 @@ class InheritingClass < RepresenterClass end it { _(InheritingClass.definitions.keys).must_equal %w[title location] } + it { assert_cloned(InheritingClass, RepresenterClass, :title) } # in inheriting class and including diff --git a/test/config_test.rb b/test/config_test.rb index 718c47ca..e160b661 100644 --- a/test/config_test.rb +++ b/test/config_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class ConfigTest < MiniTest::Spec @@ -42,14 +44,14 @@ class ConfigTest < MiniTest::Spec describe "returns" do it do # #add returns Definition.` - subject = Representable::Config.new(Representable::Definition).add(:title, {:me => true}) + subject = Representable::Config.new(Representable::Definition).add(:title, {me: true}) _(subject).must_be_kind_of Representable::Definition _(subject[:me]).must_equal true end end - before { subject.add(:title, {:me => true}) } + before { subject.add(:title, {me: true}) } # must be kind of Definition it { _(subject.size).must_equal 1 } @@ -58,15 +60,15 @@ class ConfigTest < MiniTest::Spec # this is actually tested in context in inherit_test. it "overrides former definition" do - subject.add(:title, {:peer => Module}) + subject.add(:title, {peer: Module}) _(subject.get(:title)[:me]).must_be_nil _(subject.get(:title)[:peer]).must_equal Module end describe "inherit: true" do before do - subject.add(:title, {:me => true}) - subject.add(:title, {:peer => Module, :inherit => true}) + subject.add(:title, {me: true}) + subject.add(:title, {peer: Module, inherit: true}) end it { _(subject.get(:title)[:me]).must_equal true } @@ -78,7 +80,7 @@ class ConfigTest < MiniTest::Spec subject { Representable::Config.new(Representable::Definition) } it do - subject.add(:title, {:me => true}) + subject.add(:title, {me: true}) subject.add(:genre, {}) _(subject.get(:genre)).must_be_kind_of Representable::Definition @@ -88,7 +90,7 @@ class ConfigTest < MiniTest::Spec end describe "#each" do - before { subject.add(:title, {:me => true}) } + before { subject.add(:title, {me: true}) } it "what" do definitions = [] diff --git a/test/decorator_scope_test.rb b/test/decorator_scope_test.rb index c2530542..7c66a08e 100644 --- a/test/decorator_scope_test.rb +++ b/test/decorator_scope_test.rb @@ -1,15 +1,17 @@ +# frozen_string_literal: true + require "test_helper" # TODO: remove in 2.0. class DecoratorScopeTest < MiniTest::Spec representer! do - property :title, :getter => ->(*) { title_from_representer }, :decorator_scope => true + property :title, getter: ->(*) { title_from_representer }, decorator_scope: true end let(:representer_with_method) do Module.new do include Representable::Hash - property :title, :decorator_scope => true + property :title, decorator_scope: true def title; "Crystal Planet"; end end end @@ -21,10 +23,10 @@ def title_from_representer "Sounds Of Silence" end }.new.extend(representer).to_hash - ).must_equal({"title"=>"Sounds Of Silence"}) + ).must_equal({"title" => "Sounds Of Silence"}) end it "executes method in represented context" do - _(Object.new.extend(representer_with_method).to_hash).must_equal({"title"=>"Crystal Planet"}) + _(Object.new.extend(representer_with_method).to_hash).must_equal({"title" => "Crystal Planet"}) end end diff --git a/test/decorator_test.rb b/test/decorator_test.rb index 85dbe9ab..913b1f80 100644 --- a/test/decorator_test.rb +++ b/test/decorator_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class DecoratorTest < MiniTest::Spec @@ -9,7 +11,7 @@ class SongRepresentation < Representable::Decorator class AlbumRepresentation < Representable::Decorator include Representable::JSON - collection :songs, :class => Song, :extend => SongRepresentation + collection :songs, class: Song, extend: SongRepresentation end class RatingRepresentation < Representable::Decorator @@ -31,7 +33,14 @@ class RatingRepresentation < Representable::Decorator }.new(Album.new([song], "Stand Up")) end - it { _(inherited_decorator.to_hash).must_equal({"songs" => [{"name"=>"Mama, I'm Coming Home"}], "best_song" => "Stand Up"}) } + it { + _(inherited_decorator.to_hash).must_equal( + { + "songs" => [{"name" => "Mama, I'm Coming Home"}], + "best_song" => "Stand Up" + } + ) + } end let(:decorator) { AlbumRepresentation.new(album) } @@ -39,7 +48,7 @@ class RatingRepresentation < Representable::Decorator let(:rating_decorator) { RatingRepresentation.new(rating) } it "renders" do - _(decorator.to_hash).must_equal({"songs"=>[{"name"=>"Mama, I'm Coming Home"}]}) + _(decorator.to_hash).must_equal({"songs" => [{"name" => "Mama, I'm Coming Home"}]}) _(album).wont_respond_to :to_hash _(song).wont_respond_to :to_hash # DISCUSS: weak test, how to assert blank slate? # no @representable_attrs in decorated objects @@ -50,11 +59,11 @@ class RatingRepresentation < Representable::Decorator describe "#from_hash" do it "returns represented" do - _(decorator.from_hash({"songs"=>[{"name"=>"Mama, I'm Coming Home"}]})).must_equal album + _(decorator.from_hash({"songs" => [{"name" => "Mama, I'm Coming Home"}]})).must_equal album end it "parses" do - decorator.from_hash({"songs"=>[{"name"=>"Atomic Garden"}]}) + decorator.from_hash({"songs" => [{"name" => "Atomic Garden"}]}) _(album.songs.first).must_be_kind_of Song _(album.songs).must_equal [Song.new("Atomic Garden")] _(album).wont_respond_to :to_hash @@ -70,13 +79,13 @@ class RatingRepresentation < Representable::Decorator describe "inline decorators" do representer!(decorator: true) do - collection :songs, :class => Song do + collection :songs, class: Song do property :name end end it "does not pollute represented" do - representer.new(album).from_hash({"songs"=>[{"name"=>"Atomic Garden"}]}) + representer.new(album).from_hash({"songs" => [{"name" => "Atomic Garden"}]}) # no @representable_attrs in decorated objects _(song).wont_be(:instance_variable_defined?, :@representable_attrs) diff --git a/test/default_test.rb b/test/default_test.rb index 1b22fe00..e3ca6d28 100644 --- a/test/default_test.rb +++ b/test/default_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class DefaultTest < MiniTest::Spec @@ -13,22 +15,22 @@ class DefaultTest < MiniTest::Spec it { _(song.from_hash({})).must_equal Song.new(nil, "Huber Breeze") } # default doesn't apply when empty string. - it { _(song.from_hash({"title"=>""})).must_equal Song.new(nil, "") } - it { _(song.from_hash({"title"=>nil})).must_equal Song.new(nil, nil) } - it { _(song.from_hash({"title"=>"Blindfold"})).must_equal Song.new(nil, "Blindfold") } + it { _(song.from_hash({"title" => ""})).must_equal Song.new(nil, "") } + it { _(song.from_hash({"title" => nil})).must_equal Song.new(nil, nil) } + it { _(song.from_hash({"title" => "Blindfold"})).must_equal Song.new(nil, "Blindfold") } end describe "#to_json" do it "uses :default when not available from object" do - _(Song.new.extend(representer).to_hash).must_equal({"title"=>"Huber Breeze"}) + _(Song.new.extend(representer).to_hash).must_equal({"title" => "Huber Breeze"}) end it "uses value from represented object when present" do - _(Song.new(nil, "After The War").extend(representer).to_hash).must_equal({"title"=>"After The War"}) + _(Song.new(nil, "After The War").extend(representer).to_hash).must_equal({"title" => "After The War"}) end it "uses value from represented object when emtpy string" do - _(Song.new(nil, "").extend(representer).to_hash).must_equal({"title"=>""}) + _(Song.new(nil, "").extend(representer).to_hash).must_equal({"title" => ""}) end end end diff --git a/test/defaults_options_test.rb b/test/defaults_options_test.rb index 3ca76f61..3298e3d2 100644 --- a/test/defaults_options_test.rb +++ b/test/defaults_options_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class DefaultsOptionsTest < BaseTest @@ -18,11 +20,12 @@ class DefaultsOptionsTest < BaseTest end it { - render(prepared).must_equal_document( + assert_equal_document( { "TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "DESCRIPTION" => nil, - "SONG_VOLUME" => 20 - } + "SONG_VOLUME" => 20 + }, + render(prepared) ) } end @@ -39,7 +42,12 @@ class DefaultsOptionsTest < BaseTest property :song_volume end - it { render(prepared).must_equal_document({"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "SONG_VOLUME" => 20}) } + it { + assert_equal_document( + {"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "SONG_VOLUME" => 20}, + render(prepared) + ) + } end describe "with only hashes" do @@ -53,11 +61,12 @@ class DefaultsOptionsTest < BaseTest end it { - render(prepared).must_equal_document( + assert_equal_document( { "title" => "Revolution", "author_name" => "Some author", "description" => nil, - "song_volume" => 20 - } + "song_volume" => 20 + }, + render(prepared) ) } end @@ -73,11 +82,12 @@ class DefaultsOptionsTest < BaseTest end it { - render(prepared).must_equal_document( + assert_equal_document( { "title" => "Revolution", "author_name" => "Some author", "description" => nil, - "song_volume" => 20 - } + "song_volume" => 20 + }, + render(prepared) ) } end @@ -95,11 +105,12 @@ class DefaultsOptionsTest < BaseTest end it { - render(prepared).must_equal_document( + assert_equal_document( { "TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "DESCRIPTION" => nil, - "SONG_VOLUME" => 20 - } + "SONG_VOLUME" => 20 + }, + render(prepared) ) } end @@ -116,6 +127,11 @@ class DefaultsOptionsTest < BaseTest property :song_volume, as: :volume end - it { render(prepared).must_equal_document({"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "volume" => 20}) } + it { + assert_equal_document( + {"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "volume" => 20}, + render(prepared) + ) + } end end diff --git a/test/definition_test.rb b/test/definition_test.rb index d858b36e..8e30e3f2 100644 --- a/test/definition_test.rb +++ b/test/definition_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class DefinitionTest < MiniTest::Spec @@ -7,7 +9,7 @@ class DefinitionTest < MiniTest::Spec describe "#initialize" do it do # new yields the defaultized options HASH. - definition = Definition.new(:song, :extend => Module) do |options| + definition = Definition.new(:song, extend: Module) do |options| options[:awesome] = true options[:parse_filter] << 1 @@ -31,18 +33,18 @@ class DefinitionTest < MiniTest::Spec # merge! describe "#merge!" do - let(:definition) { Definition.new(:song, :whatever => true) } + let(:definition) { Definition.new(:song, whatever: true) } # merges new options. - it { _(definition.merge!(:something => true)[:something]).must_equal true } + it { _(definition.merge!(something: true)[:something]).must_equal true } # doesn't override original options. - it { _(definition.merge!({:something => true})[:whatever]).must_equal true } + it { _(definition.merge!({something: true})[:whatever]).must_equal true } # override original when passed in #merge!. - it { _(definition.merge!({:whatever => false})[:whatever]).must_equal false } + it { _(definition.merge!({whatever: false})[:whatever]).must_equal false } # with block it do - definition = Definition.new(:song, :extend => Module).merge!({:something => true}) do |options| + definition = Definition.new(:song, extend: Module).merge!({something: true}) do |options| options[:awesome] = true options[:render_filter] << 1 @@ -58,24 +60,24 @@ class DefinitionTest < MiniTest::Spec end describe "with :parse_filter" do - let(:definition) { Definition.new(:title, :parse_filter => 1) } + let(:definition) { Definition.new(:title, parse_filter: 1) } # merges :parse_filter and :render_filter. it do - merged = definition.merge!(:parse_filter => 2)[:parse_filter] + merged = definition.merge!(parse_filter: 2)[:parse_filter] _(merged).must_be_kind_of Representable::Pipeline _(merged.size).must_equal 2 end # :parse_filter can also be array. - it { _(definition.merge!(:parse_filter => [2, 3])[:parse_filter].size).must_equal 3 } + it { _(definition.merge!(parse_filter: [2, 3])[:parse_filter].size).must_equal 3 } end # does not change arguments it do - Definition.new(:title).merge!(options = {:whatever => 1}) - _(options).must_equal(:whatever => 1) + Definition.new(:title).merge!(options = {whatever: 1}) + _(options).must_equal(whatever: 1) end end @@ -83,7 +85,7 @@ class DefinitionTest < MiniTest::Spec describe "#delete!" do let(:definition) { Definition.new(:song, serialize: "remove me!") } - before { _(definition[:serialize].(nil)).must_equal "remove me!" } + before { _(definition[:serialize].call(nil)).must_equal "remove me!" } it { _(definition.delete!(:serialize)[:serialize]).must_be_nil } end @@ -91,7 +93,7 @@ class DefinitionTest < MiniTest::Spec # #inspect describe "#inspect" do it { - _(Definition.new(:songs).inspect).must_equal "#songs @options={:name=>\"songs\", :parse_filter=>[], :render_filter=>[]}>" + _(Definition.new(:songs).inspect).must_equal '#songs @options={:name=>"songs", :parse_filter=>[], :render_filter=>[]}>' } end @@ -102,33 +104,34 @@ class DefinitionTest < MiniTest::Spec it "responds to #representer_module" do assert_nil Representable::Definition.new(:song).representer_module - assert_equal Hash, Representable::Definition.new(:song, :extend => Hash).representer_module + assert_equal Hash, Representable::Definition.new(:song, extend: Hash).representer_module end describe "#typed?" do it "is false per default" do - refute @def.typed? + refute_predicate @def, :typed? end it "is true when :class is present" do - assert Representable::Definition.new(:songs, :class => Hash).typed? + assert_predicate Representable::Definition.new(:songs, class: Hash), :typed? end it "is true when :extend is present, only" do - assert Representable::Definition.new(:songs, :extend => Hash).typed? + assert_predicate Representable::Definition.new(:songs, extend: Hash), :typed? end it "is true when :instance is present, only" do - assert Representable::Definition.new(:songs, :instance => Object.new).typed? + assert_predicate Representable::Definition.new(:songs, instance: Object.new), :typed? end end describe "#representable?" do - it { assert Definition.new(:song, :representable => true).representable? } - it { _(Definition.new(:song, :representable => true, :extend => Object).representable?).must_equal true } - it { refute Definition.new(:song, :representable => false, :extend => Object).representable? } - it { assert Definition.new(:song, :extend => Object).representable? } - it { refute Definition.new(:song).representable? } + it { assert_predicate Definition.new(:song, representable: true), :representable? } + it { _(Definition.new(:song, representable: true, extend: Object).representable?).must_equal true } + + it { refute_predicate Definition.new(:song, representable: false, extend: Object), :representable? } + it { assert_predicate Definition.new(:song, extend: Object), :representable? } + it { refute_predicate Definition.new(:song), :representable? } end it "responds to #getter and returns string" do @@ -146,42 +149,43 @@ class DefinitionTest < MiniTest::Spec describe "nested: FIXME" do it do dfn = Representable::Definition.new(:songs, nested: Module) - assert dfn.typed? - _(dfn[:extend].(nil)).must_equal Module + + assert_predicate dfn, :typed? + _(dfn[:extend].call(nil)).must_equal Module end end describe "#clone" do - subject { Representable::Definition.new(:title, :volume => 9, :clonable => ::Representable::Option(1)) } + subject { Representable::Definition.new(:title, volume: 9, clonable: ::Representable::Option(1)) } it { _(subject.clone).must_be_kind_of Representable::Definition } - it { _(subject.clone[:clonable].(nil)).must_equal 1 } + it { _(subject.clone[:clonable].call(nil)).must_equal 1 } - it "clones @options" do - @def.merge!(:volume => 9) + it 'clones @options' do + @def.merge!(volume: 9) cloned = @def.clone - cloned.merge!(:volume => 8) + cloned.merge!(volume: 8) - assert_equal @def[:volume], 9 - assert_equal cloned[:volume], 8 + assert_equal(9, @def[:volume]) + assert_equal(8, cloned[:volume]) end end end describe "#has_default?" do it "returns false if no :default set" do - refute Representable::Definition.new(:song).has_default? + refute_predicate Representable::Definition.new(:song), :has_default? end it "returns true if :default set" do - assert Representable::Definition.new(:song, :default => nil).has_default? + assert_predicate Representable::Definition.new(:song, default: nil), :has_default? end end describe "#binding" do it "returns true when :binding is set" do - assert Representable::Definition.new(:songs, :binding => Object)[:binding] + assert Representable::Definition.new(:songs, binding: Object)[:binding] end it "returns false when :binding is not set" do @@ -192,9 +196,9 @@ class DefinitionTest < MiniTest::Spec describe "#create_binding" do it "executes the block (without special context)" do definition = Representable::Definition.new( - :title, :binding => ->(*args) { - @binding = Representable::Binding.new(*args) - } + :title, binding: ->(*args) { + @binding = Representable::Binding.new(*args) + } ) _(definition.create_binding).must_equal @binding end @@ -202,40 +206,42 @@ class DefinitionTest < MiniTest::Spec describe ":collection => true" do before do - @def = Representable::Definition.new(:songs, :collection => true, :tag => :song) + @def = Representable::Definition.new(:songs, collection: true, tag: :song) end it "responds to #array?" do - assert @def.array? + assert_predicate @def, :array? end end describe ":default => value" do it "responds to #default" do @def = Representable::Definition.new(:song) + assert_nil @def[:default] end it "accepts a default value" do - @def = Representable::Definition.new(:song, :default => "Atheist Peace") + @def = Representable::Definition.new(:song, default: "Atheist Peace") + assert_equal "Atheist Peace", @def[:default] end end describe ":hash => true" do before do - @def = Representable::Definition.new(:songs, :hash => true) + @def = Representable::Definition.new(:songs, hash: true) end it "responds to #hash?" do - assert @def.hash? - refute Representable::Definition.new(:songs).hash? + assert_predicate @def, :hash? + refute_predicate Representable::Definition.new(:songs), :hash? end end describe ":binding => Object" do subject do - Representable::Definition.new(:songs, :binding => Object) + Representable::Definition.new(:songs, binding: Object) end it "responds to #binding" do diff --git a/test/examples/example.rb b/test/examples/example.rb index b8be841a..f44a3f10 100644 --- a/test/examples/example.rb +++ b/test/examples/example.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler" Bundler.setup @@ -15,7 +17,7 @@ def reset_representer(*module_name) class Song < OpenStruct end -song = Song.new(:title => "Fallout", :track => 1) +song = Song.new(title: "Fallout", track: 1) module SongRepresenter include Representable::JSON @@ -26,7 +28,7 @@ module SongRepresenter puts song.extend(SongRepresenter).to_json -rox = Song.new.extend(SongRepresenter).from_json(%{ {"title":"Roxanne"} }) +rox = Song.new.extend(SongRepresenter).from_json(%( {"title":"Roxanne"} )) puts rox.inspect module SongRepresenter @@ -52,7 +54,7 @@ module SongRepresenter collection :composers end -song = Song.new(:title => "Fallout", :composers => ["Stewart Copeland", "Sting"]) +song = Song.new(title: "Fallout", composers: ["Stewart Copeland", "Sting"]) puts song.extend(SongRepresenter).to_json ######### nesting types @@ -69,10 +71,10 @@ module AlbumRepresenter include Representable::JSON property :name - property :song, :extend => SongRepresenter, :class => Song + property :song, extend: SongRepresenter, class: Song end -album = Album.new(:name => "The Police", :song => song) +album = Album.new(name: "The Police", song: song) puts album.extend(AlbumRepresenter).to_json reset_representer(AlbumRepresenter) @@ -81,15 +83,15 @@ module AlbumRepresenter include Representable::JSON property :name - collection :songs, :extend => SongRepresenter, :class => Song + collection :songs, extend: SongRepresenter, class: Song end -album = Album.new(:name => "The Police", :songs => [song, Song.new(:title => "Synchronicity")]) +album = Album.new(name: "The Police", songs: [song, Song.new(title: "Synchronicity")]) puts album.extend(AlbumRepresenter).to_json album = Album.new.extend(AlbumRepresenter).from_json( - %{{"name":"Offspring","songs":[{"title":"Genocide"},{"title":"Nitro","composers":["Offspring"]}]} -} + %({"name":"Offspring","songs":[{"title":"Genocide"},{"title":"Nitro","composers":["Offspring"]}]} +) ) puts album.inspect @@ -104,7 +106,7 @@ def name end end -puts Album.new(:name => "The Police") +puts Album.new(name: "The Police") .extend(AlbumRepresenter).to_json reset_representer(SongRepresenter) @@ -124,7 +126,7 @@ module CoverSongRepresenter property :covered_by end -song = Song.new(:title => "Truth Hits Everybody", :covered_by => "No Use For A Name") +song = Song.new(title: "Truth Hits Everybody", covered_by: "No Use For A Name") puts song.extend(CoverSongRepresenter).to_json ### XML @@ -136,13 +138,12 @@ module SongRepresenter property :track collection :composers end -song = Song.new(:title => "Fallout", :composers => ["Stewart Copeland", "Sting"]) +song = Song.new(title: "Fallout", composers: ["Stewart Copeland", "Sting"]) puts song.extend(SongRepresenter).to_xml reset_representer(SongRepresenter) ### YAML -require "representable/yaml" module SongRepresenter include Representable::YAML @@ -162,7 +163,7 @@ module SongRepresenter property :title property :track - collection :composers, :style => :flow + collection :composers, style: :flow end puts song.extend(SongRepresenter).to_yaml @@ -171,11 +172,11 @@ module SongRepresenter end # R/W support -song = Song.new(:title => "You're Wrong", :track => 4) +song = Song.new(title: "You're Wrong", track: 4) module SongRepresenter include Representable::Hash - property :title, :readable => false + property :title, readable: false property :track end puts song.extend(SongRepresenter).to_hash @@ -187,11 +188,11 @@ module SongRepresenter module SongRepresenter include Representable::Hash - property :title, :writeable => false + property :title, writeable: false property :track end song = Song.new.extend(SongRepresenter) -song.from_hash({:title => "Fallout", :track => 1}) +song.from_hash({title: "Fallout", track: 1}) puts song ######### custom methods in representer (using helpers) @@ -202,7 +203,10 @@ module SongRepresenter class CoverSong < Song end -songs = [Song.new(title: "Weirdo", track: 5), CoverSong.new(title: "Truth Hits Everybody", track: 6, copyright: "The Police")] +songs = [ + Song.new(title: "Weirdo", track: 5), + CoverSong.new(title: "Truth Hits Everybody", track: 6, copyright: "The Police") +] album = Album.new(name: "Incognito", songs: songs) reset_representer(SongRepresenter, AlbumRepresenter) @@ -225,7 +229,7 @@ module AlbumRepresenter include Representable::Hash property :name - collection :songs, :extend => ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter } + collection :songs, extend: ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter } end puts album.extend(AlbumRepresenter).to_hash @@ -237,13 +241,13 @@ module AlbumRepresenter property :name collection :songs, - :extend => ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter }, - :class => ->(hsh) { hsh.key?("copyright") ? CoverSong : Song } #=> {"title"=>"Weirdo", "track"=>5} + extend: ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter }, + class: ->(hsh) { hsh.key?("copyright") ? CoverSong : Song } #=> {"title"=>"Weirdo", "track"=>5} end album = Album.new.extend(AlbumRepresenter).from_hash( { - "name" => "Incognito", + "name" => "Incognito", "songs" => [ {"title" => "Weirdo", "track" => 5}, {"title" => "Truth Hits Everybody", "track" => 6, "copyright" => "The Police"} @@ -259,13 +263,13 @@ module AlbumRepresenter property :name collection :songs, - :extend => ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter }, - :instance => ->(hsh) { hsh.key?("copyright") ? CoverSong.new : Song.new(original: true) } + extend: ->(song) { song.is_a?(CoverSong) ? CoverSongRepresenter : SongRepresenter }, + instance: ->(hsh) { hsh.key?("copyright") ? CoverSong.new : Song.new(original: true) } end album = Album.new.extend(AlbumRepresenter).from_hash( { - "name" => "Incognito", + "name" => "Incognito", "songs" => [ {"title" => "Weirdo", "track" => 5}, {"title" => "Truth Hits Everybody", "track" => 6, "copyright" => "The Police"} diff --git a/test/examples/object.rb b/test/examples/object.rb index 03f6b258..4c2282fc 100644 --- a/test/examples/object.rb +++ b/test/examples/object.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + require "test_helper" require "ostruct" -require "pp" source = OpenStruct.new( name: "30 Years Live", songs: [ diff --git a/test/exec_context_test.rb b/test/exec_context_test.rb index 0869cea2..6272c629 100644 --- a/test/exec_context_test.rb +++ b/test/exec_context_test.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + require "test_helper" class ExecContextTest < MiniTest::Spec for_formats( - :hash => [Representable::Hash, {Song => "Rebel Fate"}, {Song=>"Timing"}] + hash: [Representable::Hash, {Song => "Rebel Fate"}, {Song => "Timing"}] # :xml => [Representable::XML, "\n \n Alive\n \n", "You've Taken Everything/open_struct>"], # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"], ) do |format, mod, input, output| @@ -10,51 +12,53 @@ class ExecContextTest < MiniTest::Spec let(:format) { format } describe "exec_context: nil" do - representer!(:module => mod) do - property :name, :as => ->(*) { self.class } + representer!(module: mod) do + property :name, as: ->(*) { self.class } end - it { render(song).must_equal_document output } + it { assert_equal_document(render(song), output) } it { _(parse(song, input).name).must_equal "Rebel Fate" } end describe "exec_context: :decorator" do - representer!(:module => mod) do - property :name, :as => ->(*) { self.class }, :exec_context => :decorator + representer!(module: mod) do + property :name, as: ->(*) { self.class }, exec_context: :decorator end - it { render(song).must_equal_document output } + it { assert_equal_document(render(song), output) } it { _(parse(song, input).name).must_equal "Rebel Fate" } end describe "exec_context: :binding" do - representer!(:module => mod) do + representer!(module: mod) do property :name, - :as => ->(*) { self.class }, # to actually test - :exec_context => :binding, - :setter => ->(options) { - options[:represented].name = options[:fragment] # to make parsing work. - } + as: ->(*) { self.class }, # to actually test + exec_context: :binding, + setter: ->(options) { + options[:represented].name = options[:fragment] # to make parsing work. + } end - it { render(song).must_equal_document({Representable::Hash::Binding => "name"}) } + it { + assert_equal_document(render(song), {Representable::Hash::Binding => "name"}) + } it { _(parse(song, {Representable::Hash::Binding => "Rebel Fate"}).name).must_equal "Rebel Fate" } end describe "Decorator" do # DISCUSS: do we need this test? describe "exec_context: nil" do - representer!(:module => mod, :decorator => true) do - property :name, :as => ->(*) { self.class } + representer!(module: mod, decorator: true) do + property :name, as: ->(*) { self.class } end - it { render(song).must_equal_document output } + it { assert_equal_document(render(song), output) } it { _(parse(song, input).name).must_equal "Rebel Fate" } end describe "exec_context: :decorator" do # this tests if lambdas are run in the right context, if methods are called in the right context and if we can access the represented object. - representer!(:module => mod, :decorator => true) do - property :name, :as => ->(*) { self.class.superclass }, :exec_context => :decorator + representer!(module: mod, decorator: true) do + property :name, as: ->(*) { self.class.superclass }, exec_context: :decorator define_method :name do # def in Decorator class. "Timebomb" @@ -65,22 +69,22 @@ class ExecContextTest < MiniTest::Spec end end - it { render(song).must_equal_document({Representable::Decorator=>"Timebomb"}) } - it { _(parse(song, {Representable::Decorator=>"Listless"}).name).must_equal "Listless" } + it { assert_equal_document(render(song), {Representable::Decorator => "Timebomb"}) } + it { _(parse(song, {Representable::Decorator => "Listless"}).name).must_equal "Listless" } end # DISCUSS: do we need this test? describe "exec_context: :binding" do - representer!(:module => mod, :decorator => true) do + representer!(module: mod, decorator: true) do property :name, - :as => ->(*) { self.class }, # to actually test - :exec_context => :binding, - :setter => ->(options) { - options[:represented].name = options[:fragment] # to make parsing work. - } + as: ->(*) { self.class }, # to actually test + exec_context: :binding, + setter: ->(options) { + options[:represented].name = options[:fragment] # to make parsing work. + } end - it { render(song).must_equal_document({Representable::Hash::Binding => "name"}) } + it { assert_equal_document(render(song), {Representable::Hash::Binding => "name"}) } it("xxx") { _(parse(song, {Representable::Hash::Binding => "Rebel Fate"}).name).must_equal "Rebel Fate" } end end diff --git a/test/features_test.rb b/test/features_test.rb index 6f92bb46..a8f61441 100644 --- a/test/features_test.rb +++ b/test/features_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class FeaturesTest < MiniTest::Spec @@ -21,7 +23,7 @@ def length; "2:31"; end end } - let(:song) { OpenStruct.new(:details => Object.new) } + let(:song) { OpenStruct.new(details: Object.new) } describe "Module" do representer! do @@ -32,14 +34,14 @@ def length; "2:31"; end _(song.extend(representer).to_hash).must_equal( { "title" => "Is It A Lie", "length" => "2:31", - "details" => {"title"=>"Is It A Lie"} + "details" => {"title" => "Is It A Lie"} } ) } end describe "Decorator" do - representer!(:decorator => true) do + representer!(decorator: true) do instance_exec(&definition) end @@ -47,7 +49,7 @@ def length; "2:31"; end _(representer.new(song).to_hash).must_equal( { "title" => "Is It A Lie", "length" => "2:31", - "details" => {"title"=>"Is It A Lie"} + "details" => {"title" => "Is It A Lie"} } ) } @@ -82,7 +84,7 @@ def title _(representer.new(OpenStruct.new(song: Object)).to_hash).must_equal( { "title" => "I am number two, I was first!", - "song" => {"title"=>"I am number two, I was first!"} + "song" => {"title" => "I am number two, I was first!"} } ) end diff --git a/test/filter_test.rb b/test/filter_test.rb index ab4bfb39..863068a2 100644 --- a/test/filter_test.rb +++ b/test/filter_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class FilterPipelineTest < MiniTest::Spec @@ -14,15 +16,15 @@ class FilterTest < MiniTest::Spec property :title property :track, - :parse_filter => ->(input, options) { "#{input.downcase},#{options[:doc]}" }, - :render_filter => ->(val, options) { "#{val.upcase},#{options[:doc]},#{options[:options][:user_options]}" } + parse_filter: ->(input, options) { "#{input.downcase},#{options[:doc]}" }, + render_filter: ->(val, options) { "#{val.upcase},#{options[:doc]},#{options[:options][:user_options]}" } end # gets doc and options. it { song = OpenStruct.new.extend(representer).from_hash("title" => "VULCAN EARS", "track" => "Nine") _(song.title).must_equal "VULCAN EARS" - _(song.track).must_equal "nine,{\"title\"=>\"VULCAN EARS\", \"track\"=>\"Nine\"}" + _(song.track).must_equal 'nine,{"title"=>"VULCAN EARS", "track"=>"Nine"}' } it { @@ -33,18 +35,18 @@ class FilterTest < MiniTest::Spec ).extend(representer).to_hash ).must_equal({ "title" => "vulcan ears", - "track" => "NINE,{\"title\"=>\"vulcan ears\"},{}" + "track" => 'NINE,{"title"=>"vulcan ears"},{}' }) } describe "#parse_filter" do representer! do property :track, - :parse_filter => [ + parse_filter: [ ->(input, _options) { "#{input}-1" }, ->(input, _options) { "#{input}-2" } ], - :render_filter => [ + render_filter: [ ->(val, _options) { "#{val}-1" }, ->(val, _options) { "#{val}-2" } ] @@ -52,7 +54,7 @@ class FilterTest < MiniTest::Spec # order matters. it { _(OpenStruct.new.extend(representer).from_hash("track" => "Nine").track).must_equal "Nine-1-2" } - it { _(OpenStruct.new("track" => "Nine").extend(representer).to_hash).must_equal({"track"=>"Nine-1-2"}) } + it { _(OpenStruct.new("track" => "Nine").extend(representer).to_hash).must_equal({"track" => "Nine-1-2"}) } end end diff --git a/test/for_collection_test.rb b/test/for_collection_test.rb index cbe20c7b..1f7a80d7 100644 --- a/test/for_collection_test.rb +++ b/test/for_collection_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class ForCollectionTest < MiniTest::Spec @@ -13,8 +15,8 @@ module SongRepresenter # Module.for_collection # Decorator.for_collection for_formats( - :hash => [Representable::Hash, out = [{"name" => "Days Go By"}, {"name"=>"Can't Take Them All"}], out], - :json => [Representable::JSON, out = "[{\"name\":\"Days Go By\"},{\"name\":\"Can't Take Them All\"}]", out] + hash: [Representable::Hash, out = [{"name" => "Days Go By"}, {"name" => "Can't Take Them All"}], out], + json: [Representable::JSON, out = "[{\"name\":\"Days Go By\"},{\"name\":\"Can't Take Them All\"}]", out] # :xml => [Representable::XML, out="", out] ) do |format, mod, output, input| describe "Module::for_collection [#{format}]" do @@ -25,14 +27,24 @@ module SongRepresenter include mod property :name # , :as => :title - collection_representer :class => Song + collection_representer class: Song # self.representation_wrap = :songs if format == :xml end end - it { render(songs.extend(representer.for_collection)).must_equal_document output } - it { render(representer.for_collection.prepare(songs)).must_equal_document output } + it { + assert_equal_document( + render(songs.extend(representer.for_collection)), + output + ) + } + it { + assert_equal_document( + render(representer.for_collection.prepare(songs)), + output + ) + } # parsing needs the class set, at least it { _(parse([].extend(representer.for_collection), input)).must_equal songs } end @@ -48,7 +60,7 @@ module SongRepresenter end # rendering works out of the box, no config necessary - it { render(songs.extend(representer.for_collection)).must_equal_document output } + it { assert_equal_document(render(songs.extend(representer.for_collection)), output) } end describe "Decorator::for_collection [#{format}]" do @@ -58,11 +70,15 @@ module SongRepresenter include mod property :name - collection_representer :class => Song + collection_representer class: Song end end - it { render(representer.for_collection.new(songs)).must_equal_document output } + it { + assert_equal_document( + render(representer.for_collection.new(songs)), output + ) + } it { _(parse(representer.for_collection.new([]), input)).must_equal songs } end end diff --git a/test/generic_test.rb b/test/generic_test.rb index 99f67b83..97ebd78c 100644 --- a/test/generic_test.rb +++ b/test/generic_test.rb @@ -1,11 +1,18 @@ +# frozen_string_literal: true + require "test_helper" # TODO: rename/restructure to CollectionTest. class GenericTest < MiniTest::Spec let(:new_album) { OpenStruct.new.extend(representer) } - let(:album) { OpenStruct.new(:songs => ["Fuck Armageddon"]).extend(representer) } - let(:song) { OpenStruct.new(:title => "Resist Stance") } - let(:song_representer) { Module.new { include Representable::Hash; property :title } } + let(:album) { OpenStruct.new(songs: ["Fuck Armageddon"]).extend(representer) } + let(:song) { OpenStruct.new(title: "Resist Stance") } + let(:song_representer) do + Module.new do + include Representable::Hash + property :title + end + end describe "::collection" do representer! do @@ -25,14 +32,14 @@ class GenericTest < MiniTest::Spec # when collection is nil, it doesn't get rendered: for_formats( - :hash => [Representable::Hash, {}], - :xml => [Representable::XML, ""], - :yaml => [Representable::YAML, "--- {}\n"] # FIXME: this doesn't look right. + hash: [Representable::Hash, {}], + xml: [Representable::XML, ""], + yaml: [Representable::YAML, "--- {}\n"] # FIXME: this doesn't look right. ) do |format, mod, output, _input| describe "nil collections" do let(:format) { format } - representer!(:module => mod) do + representer!(module: mod) do collection :songs self.representation_wrap = :album if format == :xml end @@ -40,62 +47,62 @@ class GenericTest < MiniTest::Spec let(:album) { Album.new.extend(representer) } it "doesn't render collection in #{format}" do - render(album).must_equal_document output + assert_equal_document(render(album), output) end end end # when collection is set but empty, render the empty collection. for_formats( - :hash => [Representable::Hash, {"songs" => []}], + hash: [Representable::Hash, {"songs" => []}], # :xml => [Representable::XML, ""], - :yaml => [Representable::YAML, "---\nsongs: []\n"] + yaml: [Representable::YAML, "---\nsongs: []\n"] ) do |format, mod, output, _input| describe "empty collections" do let(:format) { format } - representer!(:module => mod) do + representer!(module: mod) do collection :songs self.representation_wrap = :album if format == :xml end - let(:album) { OpenStruct.new(:songs => []).extend(representer) } + let(:album) { OpenStruct.new(songs: []).extend(representer) } it "renders empty collection in #{format}" do - render(album).must_equal_document output + assert_equal_document(render(album), output) end end end # when collection is [], suppress rendering when render_empty: false. for_formats( - :hash => [Representable::Hash, {}], + hash: [Representable::Hash, {}], # :xml => [Representable::XML, ""], - :yaml => [Representable::YAML, "--- {}\n"] + yaml: [Representable::YAML, "--- {}\n"] ) do |format, mod, output, _input| describe "render_empty [#{format}]" do let(:format) { format } - representer!(:module => mod) do - collection :songs, :render_empty => false + representer!(module: mod) do + collection :songs, render_empty: false self.representation_wrap = :album if format == :xml end - let(:album) { OpenStruct.new(:songs => []).extend(representer) } + let(:album) { OpenStruct.new(songs: []).extend(representer) } - it { render(album).must_equal_document output } + it { assert_equal_document(render(album), output) } end end end # wrap_test for_formats( - :hash => [Representable::Hash, {}] + hash: [Representable::Hash, {}] # :xml => [Representable::XML, "\n \n Alive\n \n", "You've Taken Everything/open_struct>"], # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"], ) do |format, mod, input| describe "parsing [#{format}] with wrap where wrap is missing" do - representer!(:module => mod) do + representer!(module: mod) do self.representation_wrap = :song property :title diff --git a/test/getter_setter_test.rb b/test/getter_setter_test.rb index 95c7ff1c..f41697ec 100644 --- a/test/getter_setter_test.rb +++ b/test/getter_setter_test.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require "test_helper" class GetterSetterTest < BaseTest representer! do property :name, # key under :name. - :getter => ->(user_options:, **) { "#{user_options[:welcome]} #{song_name}" }, - :setter => ->(user_options:, input:, **) { self.song_name = "#{user_options[:welcome]} #{input}" } + getter: ->(user_options:, **) { "#{user_options[:welcome]} #{song_name}" }, + setter: ->(user_options:, input:, **) { self.song_name = "#{user_options[:welcome]} #{input}" } end subject { Struct.new(:song_name).new("Mony Mony").extend(representer) } @@ -15,7 +17,12 @@ class GetterSetterTest < BaseTest end it "uses :setter when parsing" do - subject.instance_eval { def name=(*); fail; end; self } + subject.instance_eval do + def name=(*) + fail + end + self + end _( subject.from_hash( {"name" => "Eyes Without A Face"}, diff --git a/test/hash_bindings_test.rb b/test/hash_bindings_test.rb index 722f3d6e..990a01cf 100644 --- a/test/hash_bindings_test.rb +++ b/test/hash_bindings_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class HashBindingTest < MiniTest::Spec @@ -37,7 +39,12 @@ class SongWithRepresenter < ::Song describe "CollectionBinding" do describe "with plain text items" do before do - @property = Representable::Hash::Binding::Collection.new(Representable::Definition.new(:songs, :collection => true)) + @property = Representable::Hash::Binding::Collection.new( + Representable::Definition.new( + :songs, + collection: true + ) + ) end it "extracts with #read" do @@ -46,8 +53,9 @@ class SongWithRepresenter < ::Song it "inserts with #write" do doc = {} + assert_equal(["The Gargoyle", "Bronx"], @property.write(doc, ["The Gargoyle", "Bronx"], "songs")) - assert_equal({"songs"=>["The Gargoyle", "Bronx"]}, doc) + assert_equal({"songs" => ["The Gargoyle", "Bronx"]}, doc) end end end @@ -55,7 +63,7 @@ class SongWithRepresenter < ::Song describe "HashBinding" do describe "with plain text items" do before do - @property = Representable::Hash::Binding.new(Representable::Definition.new(:songs, :hash => true)) + @property = Representable::Hash::Binding.new(Representable::Definition.new(:songs, hash: true)) end it "extracts with #read" do @@ -67,11 +75,12 @@ class SongWithRepresenter < ::Song it "inserts with #write" do doc = {} + assert_equal( {"first" => "The Gargoyle", "second" => "Bronx"}, @property.write(doc, {"first" => "The Gargoyle", "second" => "Bronx"}, "songs") ) - assert_equal({"songs"=>{"first" => "The Gargoyle", "second" => "Bronx"}}, doc) + assert_equal({"songs" => {"first" => "The Gargoyle", "second" => "Bronx"}}, doc) end end @@ -79,8 +88,8 @@ class SongWithRepresenter < ::Song before do @property = Representable::Hash::Binding.new( Representable::Definition.new( - :songs, :hash => true, :class => Song, - :extend => SongRepresenter + :songs, hash: true, class: Song, + extend: SongRepresenter ) ) end @@ -89,6 +98,7 @@ class SongWithRepresenter < ::Song song = Song.new("Better Than That") hash = {"first" => song} @property.write({}, hash, "song") + assert_equal({"first" => song}, hash) end end diff --git a/test/hash_test.rb b/test/hash_test.rb index 0aa2bb91..061de13f 100644 --- a/test/hash_test.rb +++ b/test/hash_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class HashPublicMethodsTest < Minitest::Spec @@ -55,7 +57,7 @@ class HashWithTypedPropertyTest < MiniTest::Spec Album = Struct.new(:best_song) representer! do - property :best_song, :class => Song do + property :best_song, class: Song do property :name end end @@ -100,15 +102,17 @@ class HashWithTypedPropertyTest < MiniTest::Spec # TODO: move to AsTest. class HashWithTypedPropertyAndAs < MiniTest::Spec representer! do - property :song, :class => Song, :as => :hit do + property :song, class: Song, as: :hit do property :name end end - let(:album) { OpenStruct.new(:song => Song.new("Liar")).extend(representer) } + let(:album) { OpenStruct.new(song: Song.new("Liar")).extend(representer) } it { _(album.to_hash).must_equal("hit" => {"name" => "Liar"}) } - it { _(album.from_hash("hit" => {"name" => "Go With Me"})).must_equal OpenStruct.new(:song => Song.new("Go With Me")) } + it { + _(album.from_hash("hit" => {"name" => "Go With Me"})).must_equal OpenStruct.new(song: Song.new("Go With Me")) + } end # # describe "FIXME COMBINE WITH ABOVE with :extend and :as" do # # hash_song = Module.new do @@ -160,7 +164,7 @@ class HashWithTypedCollectionTest < MiniTest::Spec "songs" => [ {"name" => "One Shot Deal", "track" => 4}, { - "name" => "Three Way Dance", + "name" => "Three Way Dance", "track" => 5 } ] diff --git a/test/heritage_test.rb b/test/heritage_test.rb index c8385fd3..7e99c75e 100644 --- a/test/heritage_test.rb +++ b/test/heritage_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class HeritageTest < Minitest::Spec @@ -34,15 +36,15 @@ class C < A end it "B must inherit Hello! feature from A" do - _(B.representable_attrs.get(:id)[:extend].(nil).new(nil).hello).must_equal "Hello!" + _(B.representable_attrs.get(:id)[:extend].call(nil).new(nil).hello).must_equal "Hello!" end it "B must have Ciao from module (feauture) Ciao" do - _(B.representable_attrs.get(:id)[:extend].(nil).new(nil).ciao).must_equal "Ciao!" + _(B.representable_attrs.get(:id)[:extend].call(nil).new(nil).ciao).must_equal "Ciao!" end it "C must inherit Hello! feature from A" do - _(C.representable_attrs.get(:id)[:extend].(nil).new(nil).hello).must_equal "Hello!" + _(C.representable_attrs.get(:id)[:extend].call(nil).new(nil).hello).must_equal "Hello!" end module M diff --git a/test/if_test.rb b/test/if_test.rb index d08ac441..228fd026 100644 --- a/test/if_test.rb +++ b/test/if_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class IfTest < MiniTest::Spec @@ -11,40 +13,47 @@ class IfTest < MiniTest::Spec end it "respects property when condition true" do - band_class.class_eval { property :fame, :if => ->(*) { true } } + band_class.class_eval { property :fame, if: ->(*) { true } } band = band_class.new - band.from_hash({"fame"=>"oh yes"}) + band.from_hash({"fame" => "oh yes"}) + assert_equal "oh yes", band.fame end it "ignores property when condition false" do - band_class.class_eval { property :fame, :if => ->(*) { false } } + band_class.class_eval { property :fame, if: ->(*) { false } } band = band_class.new - band.from_hash({"fame"=>"oh yes"}) + band.from_hash({"fame" => "oh yes"}) + assert_nil band.fame end it "ignores property when :exclude'ed even when condition is true" do - band_class.class_eval { property :fame, :if => ->(*) { true } } + band_class.class_eval { property :fame, if: ->(*) { true } } band = band_class.new - band.from_hash({"fame"=>"oh yes"}, {:exclude => [:fame]}) + band.from_hash({"fame" => "oh yes"}, {exclude: [:fame]}) + assert_nil band.fame end it "executes block in instance context" do - band_class.class_eval { property :fame, :if => ->(*) { groupies }; attr_accessor :groupies } + band_class.class_eval do + property :fame, if: ->(*) { groupies } + attr_accessor :groupies + end band = band_class.new band.groupies = true - band.from_hash({"fame"=>"oh yes"}) + band.from_hash({"fame" => "oh yes"}) + assert_equal "oh yes", band.fame end describe "executing :if lambda in represented instance context" do representer! do - property :label, :if => ->(*) { signed_contract } + property :label, if: ->(*) { signed_contract } end - subject { OpenStruct.new(:signed_contract => false, :label => "Fat") } + subject { OpenStruct.new(signed_contract: false, label: "Fat") } it "skips when false" do _(subject.extend(representer).to_hash).must_equal({}) @@ -52,7 +61,7 @@ class IfTest < MiniTest::Spec it "represents when true" do subject.signed_contract = true - _(subject.extend(representer).to_hash).must_equal({"label"=>"Fat"}) + _(subject.extend(representer).to_hash).must_equal({"label" => "Fat"}) end it "works with decorator" do @@ -68,9 +77,9 @@ class IfTest < MiniTest::Spec describe "propagating user options to the block" do representer! do - property :name, :if => ->(opts) { opts[:user_options][:include_name] } + property :name, if: ->(opts) { opts[:user_options][:include_name] } end - subject { OpenStruct.new(:name => "Outbound").extend(representer) } + subject { OpenStruct.new(name: "Outbound").extend(representer) } it "works without specifying options" do _(subject.to_hash).must_equal({}) diff --git a/test/include_exclude_test.rb b/test/include_exclude_test.rb index 4e65ee34..de967e68 100644 --- a/test/include_exclude_test.rb +++ b/test/include_exclude_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class IncludeExcludeTest < Minitest::Spec @@ -22,14 +24,14 @@ class IncludeExcludeTest < Minitest::Spec describe "#from_hash" do it "accepts :exclude option" do - decorator.from_hash({"title" => "Don't Smile In Trouble", "artist" => {"id"=>2}}, exclude: [:title]) + decorator.from_hash({"title" => "Don't Smile In Trouble", "artist" => {"id" => 2}}, exclude: [:title]) _(song.title).must_equal "Listless" _(song.artist).must_equal Artist.new(nil, 2) end it "accepts :include option" do - decorator.from_hash({"title" => "Don't Smile In Trouble", "artist" => {"id"=>2}}, include: [:title]) + decorator.from_hash({"title" => "Don't Smile In Trouble", "artist" => {"id" => 2}}, include: [:title]) _(song.title).must_equal "Don't Smile In Trouble" _(song.artist).must_equal Artist.new("7yearsbadluck", 1) @@ -38,13 +40,13 @@ class IncludeExcludeTest < Minitest::Spec it "accepts nested :exclude/:include option" do decorator.from_hash( { - "title" => "Don't Smile In Trouble", + "title" => "Don't Smile In Trouble", "artist" => {"name" => "Foo", "id" => 2, "songs" => [{"id" => 1, "title" => "Listless"}]} }, exclude: [:title], - artist: { + artist: { exclude: [:id], - songs: {include: [:title]} + songs: {include: [:title]} } ) @@ -55,11 +57,11 @@ class IncludeExcludeTest < Minitest::Spec describe "#to_hash" do it "accepts :exclude option" do - _(decorator.to_hash(exclude: [:title])).must_equal({"artist"=>{"name" => "7yearsbadluck", "id" => 1}}) + _(decorator.to_hash(exclude: [:title])).must_equal({"artist" => {"name" => "7yearsbadluck", "id" => 1}}) end it "accepts :include option" do - _(decorator.to_hash(include: [:title])).must_equal({"title"=>"Listless"}) + _(decorator.to_hash(include: [:title])).must_equal({"title" => "Listless"}) end it "accepts nested :exclude/:include option" do @@ -68,12 +70,12 @@ class IncludeExcludeTest < Minitest::Spec _( decorator.to_hash( exclude: [:title], - artist: { + artist: { exclude: [:id], - songs: {include: [:title]} + songs: {include: [:title]} } ) - ).must_equal({"artist"=>{"name" => "7yearsbadluck", "songs" => [{"title"=>"C.O.A.B.I.E.T.L."}]}}) + ).must_equal({"artist" => {"name" => "7yearsbadluck", "songs" => [{"title" => "C.O.A.B.I.E.T.L."}]}}) end end @@ -90,7 +92,7 @@ class IncludeExcludeTest < Minitest::Spec _( Cover.new("Roxanne", Cover.new("Roxanne (Don't Put On The Red Light)")).extend(cover_rpr) - .to_hash(:include => [:original]) - ).must_equal({"original"=>{"title"=>"Roxanne (Don't Put On The Red Light)"}}) + .to_hash(include: [:original]) + ).must_equal({"original" => {"title" => "Roxanne (Don't Put On The Red Light)"}}) end end diff --git a/test/inherit_test.rb b/test/inherit_test.rb index 2521854f..dc39ac29 100644 --- a/test/inherit_test.rb +++ b/test/inherit_test.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + require "test_helper" class InheritTest < MiniTest::Spec # it's important to have a global module so we can test if stuff gets overridden in the original module. module SongRepresenter include Representable::Hash - property :name, :as => :title do - property :string, :as => :str + property :name, as: :title do + property :string, as: :str end - property :track, :as => :no + property :track, as: :no end let(:song) { Song.new(Struct.new(:string).new("Roxanne"), 1) } @@ -17,18 +19,20 @@ module SongRepresenter representer! do include SongRepresenter - property :track, :inherit => true, :getter => ->(*) { "n/a" } + property :track, inherit: true, getter: ->(*) { "n/a" } end - it { _(SongRepresenter.prepare(song).to_hash).must_equal({"title" => {"str"=>"Roxanne"}, "no" => 1}) } - it { _(representer.prepare(song).to_hash).must_equal({"title" => {"str"=>"Roxanne"}, "no" => "n/a"}) } # as: inherited. + it { _(SongRepresenter.prepare(song).to_hash).must_equal({"title" => {"str" => "Roxanne"}, "no" => 1}) } + it { + _(representer.prepare(song).to_hash).must_equal({"title" => {"str" => "Roxanne"}, "no" => "n/a"}) + } # as: inherited. end describe ":inherit with empty inline representer" do representer! do include SongRepresenter - property :name, :inherit => true do # inherit as: title + property :name, inherit: true do # inherit as: title # that doesn't make sense. end end @@ -41,7 +45,7 @@ module SongRepresenter 1 ) ).to_hash - ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1}) + ).must_equal({"title" => {"str" => "Believe It"}, "no" => 1}) } # the block doesn't override the inline representer. it { @@ -52,7 +56,7 @@ module SongRepresenter 1 ) ).to_hash - ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1}) + ).must_equal({"title" => {"str" => "Believe It"}, "no" => 1}) } end @@ -61,8 +65,8 @@ module SongRepresenter include SongRepresenter # passing block - property :name, :inherit => true do # inherit as: title - property :string, :as => :s + property :name, inherit: true do # inherit as: title + property :string, as: :s property :length end end @@ -96,7 +100,7 @@ module SongRepresenter 1 ) ).to_hash - ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1}) + ).must_equal({"title" => {"str" => "Believe It"}, "no" => 1}) } it { _( @@ -106,7 +110,7 @@ module SongRepresenter 1 ) ).to_hash - ).must_equal({"name" => {"str"=>"Believe It"}, "no" => 1}) + ).must_equal({"name" => {"str" => "Believe It"}, "no" => 1}) } end @@ -114,7 +118,7 @@ module SongRepresenter representer! do include SongRepresenter - property :name, :inherit => true, :as => :name # FIXME: add :getter or something else dynamic since this is double-wrapped. + property :name, inherit: true, as: :name # FIXME: add :getter or something else dynamic since this is double-wrapped. end it { @@ -125,7 +129,7 @@ module SongRepresenter 1 ) ).to_hash - ).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1}) + ).must_equal({"title" => {"str" => "Believe It"}, "no" => 1}) } it { _( @@ -135,7 +139,7 @@ module SongRepresenter 1 ) ).to_hash - ).must_equal({"name" => {"str"=>"Believe It"}, "no" => 1}) + ).must_equal({"name" => {"str" => "Believe It"}, "no" => 1}) } end @@ -144,7 +148,7 @@ module SongRepresenter representer! do include SongRepresenter - property :track, :representable => true + property :track, representable: true end it "replaces inherited property" do @@ -159,7 +163,7 @@ module SongRepresenter # decorator describe ":inherit with decorator" do - representer!(:decorator => true) do + representer!(decorator: true) do property :hit do property :title, exec_context: :decorator @@ -172,7 +176,7 @@ def title let(:inheriting) do class InheritingDecorator < representer include Representable::Debug - property :hit, :inherit => true do + property :hit, inherit: true do include Representable::Debug property :length end @@ -186,12 +190,12 @@ class InheritingDecorator < representer OpenStruct.new( hit: OpenStruct.new( title: "I WILL BE OVERRIDDEN", - :length => "2:59" + length: "2:59" ) ) ).to_hash ).must_equal( - {"hit"=>{"title"=>"Cheap Transistor Radio"}} + {"hit" => {"title" => "Cheap Transistor Radio"}} ) } @@ -201,9 +205,9 @@ class InheritingDecorator < representer _( inheriting.new( OpenStruct.new( - :hit => OpenStruct.new( - :title => "Hole In Your Soul", - :length => "2:59" + hit: OpenStruct.new( + title: "Hole In Your Soul", + length: "2:59" ) ) ).to_hash @@ -220,10 +224,10 @@ class InheritingDecorator < representer # :inherit when property doesn't exist, yet. describe ":inherit without inheritable property" do representer! do - property :name, :inherit => true + property :name, inherit: true end - it { _(representer.prepare(Song.new("The Beginning")).to_hash).must_equal({"name"=>"The Beginning"}) } + it { _(representer.prepare(Song.new("The Beginning")).to_hash).must_equal({"name" => "The Beginning"}) } end end diff --git a/test/inline_test.rb b/test/inline_test.rb index 0379141a..58bb8485 100644 --- a/test/inline_test.rb +++ b/test/inline_test.rb @@ -2,57 +2,69 @@ class InlineTest < MiniTest::Spec let(:song) { Song.new("Alive") } - let(:request) { representer.prepare(OpenStruct.new(:song => song)) } + let(:request) { representer.prepare(OpenStruct.new(song: song)) } { - :hash => [Representable::Hash, {"song"=>{"name"=>"Alive"}}, {"song"=>{"name"=>"You've Taken Everything"}}], - :json => [Representable::JSON, "{\"song\":{\"name\":\"Alive\"}}", "{\"song\":{\"name\":\"You've Taken Everything\"}}"], - :xml => [ + hash: [ + Representable::Hash, {"song" => {"name" => "Alive"}}, + {"song" => {"name" => "You've Taken Everything"}} + ], + json: [ + Representable::JSON, '{"song":{"name":"Alive"}}', + "{\"song\":{\"name\":\"You've Taken Everything\"}}" + ], + xml: [ Representable::XML, "\n \n Alive\n \n", "You've Taken Everything/open_struct>" ], - :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"] + yaml: [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"] }.each do |format, cfg| mod, output, input = cfg describe "[#{format}] with :class" do - representer!(:module => mod) do - property :song, :class => Song do + representer!(module: mod) do + property :song, class: Song do property :name end end let(:format) { format } - it { render(request).must_equal_document output } + it { assert_equal_document(output, render(request)) } it { _(parse(request, input).song.name).must_equal "You've Taken Everything" } end end { - :hash => [Representable::Hash, {"songs"=>[{"name"=>"Alive"}]}, {"songs"=>[{"name"=>"You've Taken Everything"}]}], - :json => [Representable::JSON, "{\"songs\":[{\"name\":\"Alive\"}]}", "{\"songs\":[{\"name\":\"You've Taken Everything\"}]}"], - :xml => [ + hash: [ + Representable::Hash, {"songs" => [{"name" => "Alive"}]}, + {"songs" => [{"name" => "You've Taken Everything"}]} + ], + json: [ + Representable::JSON, '{"songs":[{"name":"Alive"}]}', + "{\"songs\":[{\"name\":\"You've Taken Everything\"}]}" + ], + xml: [ Representable::XML, "\n \n Alive\n \n", - "You've Taken Everything", {:as => :song} + "You've Taken Everything", {as: :song} ], - :yaml => [Representable::YAML, "---\nsongs:\n- name: Alive\n", "---\nsongs:\n- name: You've Taken Everything\n"] + yaml: [Representable::YAML, "---\nsongs:\n- name: Alive\n", "---\nsongs:\n- name: You've Taken Everything\n"] }.each do |format, cfg| mod, output, input, collection_options = cfg collection_options ||= {} describe "[#{format}] collection with :class" do - let(:request) { representer.prepare(OpenStruct.new(:songs => [song])) } + let(:request) { representer.prepare(OpenStruct.new(songs: [song])) } - representer!(:module => mod) do - collection :songs, collection_options.merge(:class => Song) do + representer!(module: mod) do + collection :songs, collection_options.merge(class: Song) do property :name end end let(:format) { format } # FIXME: why do we have to define this? - it { render(request).must_equal_document output } + it { assert_equal_document(render(request), output) } it { _(parse(request, input).songs.first.name).must_equal "You've Taken Everything" } end end @@ -64,16 +76,16 @@ class InlineTest < MiniTest::Spec end end - it { _(request.to_hash).must_equal({"song"=>{"name"=>"Alive"}}) } + it { _(request.to_hash).must_equal({"song" => {"name" => "Alive"}}) } end for_formats( - :hash => [Representable::Hash, {}] + hash: [Representable::Hash, {}] # :xml => [Representable::XML, "\n \n Alive\n \n", "You've Taken Everything/open_struct>"], # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"], ) do |format, mod, input| describe "parsing [#{format}] where nested property missing" do - representer!(:module => mod) do + representer!(module: mod) do property :song do property :name end @@ -89,23 +101,25 @@ class InlineTest < MiniTest::Spec let(:request) { Struct.new(:song, :requester).new(song, "Josephine") } [false, true].each do |is_decorator| # test for module and decorator. - representer!(:decorator => is_decorator) do + representer!(decorator: is_decorator) do property :requester - property :song, :class => Song do + property :song, class: Song do property :name end end let(:decorator) { representer.prepare(request) } - it { _(decorator.to_hash).must_equal({"requester" => "Josephine", "song" => {"name"=>"Alive"}}) } - it { _(decorator.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name).must_equal "You've Taken Everything" } + it { _(decorator.to_hash).must_equal({"requester" => "Josephine", "song" => {"name" => "Alive"}}) } + it { + _(decorator.from_hash({"song" => {"name" => "You've Taken Everything"}}).song.name).must_equal "You've Taken Everything" + } end end describe "object pollution" do - representer!(:decorator => true) do + representer!(decorator: true) do property :song do property :name end @@ -149,7 +163,7 @@ class InlineTest < MiniTest::Spec for_formats( { - :hash => [Representable::Hash, {"album" => {"artist" => {"label"=>"Epitaph"}}}] + hash: [Representable::Hash, {"album" => {"artist" => {"label" => "Epitaph"}}}] # :xml => [Representable::XML, ""], # :yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n"] } @@ -162,16 +176,16 @@ class ArtistDecorator < Representable::Decorator describe ":getter with :decorator" do let(:format) { format } - representer!(:module => mod) do + representer!(module: mod) do self.representation_wrap = "album" - property :artist, :getter => ->(_args) { represented }, :decorator => ArtistDecorator + property :artist, getter: ->(_args) { represented }, decorator: ArtistDecorator end - let(:album) { OpenStruct.new(:label => "Epitaph").extend(representer) } + let(:album) { OpenStruct.new(label: "Epitaph").extend(representer) } it "renders nested Album-properties in separate section" do - render(album).must_equal_document output + assert_equal_document(render(album), output) end end end @@ -179,20 +193,20 @@ class ArtistDecorator < Representable::Decorator # test helper methods within inline representer for_formats( { - :hash => [Representable::Hash, {"song"=>{"name"=>"ALIVE"}}], - :xml => [Representable::XML, "\n \n ALIVE\n \n"], - :yaml => [Representable::YAML, "---\nsong:\n name: ALIVE\n"] + hash: [Representable::Hash, {"song" => {"name" => "ALIVE"}}], + xml: [Representable::XML, "\n \n ALIVE\n \n"], + yaml: [Representable::YAML, "---\nsong:\n name: ALIVE\n"] } ) do |format, mod, output| describe "helper method within inline representer [#{format}]" do let(:format) { format } - representer!(:module => mod, :decorator => true) do + representer!(module: mod, decorator: true) do self.representation_wrap = :request if format == :xml property :requester property :song do - property :name, :exec_context => :decorator + property :name, exec_context: :decorator define_method :name do represented.name.upcase @@ -202,10 +216,10 @@ class ArtistDecorator < Representable::Decorator end end - let(:request) { representer.prepare(OpenStruct.new(:song => Song.new("Alive"))) } + let(:request) { representer.prepare(OpenStruct.new(song: Song.new("Alive"))) } it do - render(request).must_equal_document output + assert_equal_document(render(request), output) end end end @@ -226,14 +240,14 @@ class ArtistDecorator < Representable::Decorator it do _( OpenStruct.new( - :song => OpenStruct.new( - :title => "The Fever And The Sound", - :artist => "Strung Out" + song: OpenStruct.new( + title: "The Fever And The Sound", + artist: "Strung Out" ) ).extend(representer) .to_hash ) - .must_equal({"song"=>{"artist" => "Strung Out", "title" => "The Fever And The Sound"}}) + .must_equal({"song" => {"artist" => "Strung Out", "title" => "The Fever And The Sound"}}) end end @@ -255,7 +269,12 @@ def duration end end - it { _(Object.new.extend(Mod).to_hash).must_equal("song"=>{"duration"=>"6:53"}) } + it { + assert_equal( + {"song" => {"duration" => "6:53"}}, + OpenStruct.new.extend(Mod).to_hash + ) + } end # define method inline with Decorator @@ -267,8 +286,8 @@ def song "Object.new" end - property :song, :exec_context => :decorator do - property :duration, :exec_context => :decorator + property :song, exec_context: :decorator do + property :duration, exec_context: :decorator def duration "6:53" @@ -276,6 +295,6 @@ def duration end end - it { _(dec.new(Object.new).to_hash).must_equal("song"=>{"duration"=>"6:53"}) } + it { _(dec.new(Object.new).to_hash).must_equal("song" => {"duration" => "6:53"}) } end end diff --git a/test/instance_test.rb b/test/instance_test.rb index f6a24496..8450307c 100644 --- a/test/instance_test.rb +++ b/test/instance_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class InstanceTest < BaseTest @@ -10,7 +12,7 @@ def self.find(id) describe "lambda { fragment } (new way of class: lambda { nil })" do representer! do - property :title, :instance => ->(options) { options[:fragment] } + property :title, instance: ->(options) { options[:fragment] } end it "skips creating new instance" do @@ -29,35 +31,37 @@ def from_hash(hash, *_args) # TODO: use *args in from_hash. # DISCUSS: do we need parse_strategy? describe "property with :instance" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do property :song, - :instance => ->(options) { options[:fragment]["id"] == song.id ? song : Song.find(options[:fragment]["id"]) }, - :extend => song_representer + instance: ->(options) { + options[:fragment]["id"] == song.id ? song : Song.find(options[:fragment]["id"]) + }, + extend: song_representer end it("xxx") { _( - OpenStruct.new(:song => Song.new(1, "The Answer Is Still No")).extend(representer) + OpenStruct.new(song: Song.new(1, "The Answer Is Still No")).extend(representer) .from_hash("song" => {"id" => 1}).song ).must_equal Song.new(1, "The Answer Is Still No") } it { _( - OpenStruct.new(:song => Song.new(1, "The Answer Is Still No")).extend(representer) + OpenStruct.new(song: Song.new(1, "The Answer Is Still No")).extend(representer) .from_hash("song" => {"id" => 2}).song ).must_equal Song.new(2, "Invincible") } end describe "collection with :instance" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do collection :songs, - :instance => ->(options) { + instance: ->(options) { options[:fragment]["id"] == songs[options[:index]].id ? songs[options[:index]] : Song.find(options[:fragment]["id"]) }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync. - :extend => song_representer + extend: song_representer end it { @@ -79,17 +83,17 @@ def from_hash(hash, *_args) end describe "property with lambda receiving fragment and args" do - representer!(:inject => :song_representer) do - property :song, :instance => ->(options) { - Struct.new(:args, :id).new([options[:fragment], options[:user_options]]) - }, :extend => song_representer + representer!(inject: :song_representer) do + property :song, instance: ->(options) { + Struct.new(:args, :id).new([options[:fragment], options[:user_options]]) + }, extend: song_representer end it { _( - OpenStruct.new(:song => Song.new(1, "The Answer Is Still No")).extend(representer) + OpenStruct.new(song: Song.new(1, "The Answer Is Still No")).extend(representer) .from_hash({"song" => {"id" => 1}}, user_options: {volume: 1}).song.args - ).must_equal([{"id"=>1}, {:volume=>1}]) + ).must_equal([{"id" => 1}, {volume: 1}]) } end @@ -116,14 +120,14 @@ def from_hash(hash, *_args) # lambda { |fragment, i, Context(binding: <..>, args: [..])| } describe "sync" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do collection :songs, - :instance => ->(options) { + instance: ->(options) { songs[options[:index]] }, - :extend => song_representer, + extend: song_representer, # :parse_strategy => :sync - :setter => ->(*) {} + setter: ->(*) {} end it { @@ -150,16 +154,16 @@ def from_hash(hash, *_args) end describe "update existing elements, only" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do collection :songs, - :instance => ->(options) { + instance: ->(options) { # fragment["id"] == songs[i].id ? songs[i] : Song.find(fragment["id"]) songs.find { |s| s.id == options[:fragment]["id"] } }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync. - :extend => song_representer, + extend: song_representer, # :parse_strategy => :sync - :setter => ->(*) {} + setter: ->(*) {} end it("hooray") { @@ -188,16 +192,16 @@ def from_hash(hash, *_args) end describe "add incoming elements, only" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do collection :songs, - :instance => ->(_options) { + instance: ->(_options) { songs << song = Song.new(2) song }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync. - :extend => song_representer, + extend: song_representer, # :parse_strategy => :sync - :setter => ->(*) {} + setter: ->(*) {} end it { @@ -224,18 +228,18 @@ def from_hash(hash, *_args) # not sure if this must be a library strategy describe "replace existing element" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do collection :songs, - :instance => ->(options) { + instance: ->(options) { id = options[:fragment].delete("replace_id") replaced = songs.find { |s| s.id == id } songs[songs.index(replaced)] = song = Song.new(3) song }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync. - :extend => song_representer, + extend: song_representer, # :parse_strategy => :sync - :setter => ->(*) {} + setter: ->(*) {} end it { @@ -262,9 +266,9 @@ def from_hash(hash, *_args) end describe "replace collection" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do collection :songs, - :extend => song_representer, :class => Song + extend: song_representer, class: Song end it { diff --git a/test/is_representable_test.rb b/test/is_representable_test.rb index 88522113..275a2233 100644 --- a/test/is_representable_test.rb +++ b/test/is_representable_test.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + require "test_helper" class IsRepresentableTest < BaseTest describe "representable: false, extend:" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do property :song, - :representable => false, - :extend => song_representer + representable: false, + extend: song_representer end it "does extend but doesn't call #to_hash" do @@ -18,9 +20,9 @@ class IsRepresentableTest < BaseTest end describe "representable: true, no extend:" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do property :song, - :representable => true + representable: true end it "doesn't extend but calls #to_hash" do @@ -42,9 +44,9 @@ def to_hash(*) # TODO: TEST implement for from_hash. describe "representable: false, with class:" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do property :song, - :representable => false, :class => OpenStruct, :extend => song_representer + representable: false, class: OpenStruct, extend: song_representer end it "does extend but doesn't call #from_hash" do @@ -63,9 +65,9 @@ def from_hash(*) end end - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do property :song, - :representable => true, :class => SongReader + representable: true, class: SongReader end it "doesn't extend but calls #from_hash" do diff --git a/test/json_test.rb b/test/json_test.rb index 48d00981..e643e4f1 100644 --- a/test/json_test.rb +++ b/test/json_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" require "json" @@ -47,11 +49,12 @@ def initialize(name = nil) describe "#from_json" do before do @band = @Band.new - @json = {:name => "Nofx", :label => "NOFX"}.to_json + @json = {name: "Nofx", label: "NOFX"}.to_json end it "parses JSON and assigns properties" do @band.from_json(@json) + assert_equal %w[Nofx NOFX], [@band.name, @band.label] end end @@ -64,11 +67,13 @@ def initialize(name = nil) it "receives hash and assigns properties" do @band.from_hash(@hash) + assert_equal %w[Nofx NOFX], [@band.name, @band.label] end it "respects :wrap option" do - @band.from_hash({"band" => {"name" => "This Is A Standoff"}}, :wrap => :band) + @band.from_hash({"band" => {"name" => "This Is A Standoff"}}, wrap: :band) + assert_equal "This Is A Standoff", @band.name end @@ -76,32 +81,35 @@ def initialize(name = nil) @Band.class_eval do self.representation_wrap = :group end - @band.from_hash({"band" => {"name" => "This Is A Standoff"}}, :wrap => :band) + @band.from_hash({"band" => {"name" => "This Is A Standoff"}}, wrap: :band) + assert_equal "This Is A Standoff", @band.name end end describe "#to_json" do it "delegates to #to_hash and returns string" do - assert_json "{\"name\":\"Rise Against\"}", @Band.new("Rise Against").to_json + assert_json '{"name":"Rise Against"}', @Band.new("Rise Against").to_json end end describe "#to_hash" do it "returns unwrapped hash" do hash = @Band.new("Rise Against").to_hash - assert_equal({"name"=>"Rise Against"}, hash) + + assert_equal({"name" => "Rise Against"}, hash) end it "respects :wrap option" do - assert_equal({:band=>{"name"=>"NOFX"}}, @Band.new("NOFX").to_hash(:wrap => :band)) + assert_equal({band: {"name" => "NOFX"}}, @Band.new("NOFX").to_hash(wrap: :band)) end it "respects :wrap option over representation_wrap" do @Band.class_eval do self.representation_wrap = :group end - assert_equal({:band=>{"name"=>"Rise Against"}}, @Band.new("Rise Against").to_hash(:wrap => :band)) + + assert_equal({band: {"name" => "Rise Against"}}, @Band.new("Rise Against").to_hash(wrap: :band)) end end @@ -112,7 +120,7 @@ def initialize(name = nil) it "returns CollectionBinding" do assert_kind_of Representable::Hash::Binding::Collection, - Representable::Hash::Binding.build_for(Def.new(:band, :collection => true)) + Representable::Hash::Binding.build_for(Def.new(:band, collection: true)) end end end @@ -125,8 +133,8 @@ module SongRepresenter module AlbumRepresenter include Representable::JSON - property :best_song, :class => Song, :extend => SongRepresenter - collection :songs, :class => Song, :extend => SongRepresenter + property :best_song, class: Song, extend: SongRepresenter + collection :songs, class: Song, extend: SongRepresenter end it "allows adding the representer by using #extend" do @@ -145,14 +153,15 @@ def name=(v) end civ.extend(BandRepresenter) - assert_json "{\"name\":\"CIV\"}", civ.to_json + + assert_json '{"name":"CIV"}', civ.to_json end it "extends contained models when serializing" do @album = Album.new([Song.new("I Hate My Brain"), mr = Song.new("Mr. Charisma")], mr) @album.extend(AlbumRepresenter) - assert_json "{\"best_song\":{\"name\":\"Mr. Charisma\"},\"songs\":[{\"name\":\"I Hate My Brain\"},{\"name\":\"Mr. Charisma\"}]}", + assert_json '{"best_song":{"name":"Mr. Charisma"},"songs":[{"name":"I Hate My Brain"},{"name":"Mr. Charisma"}]}', @album.to_json end @@ -161,7 +170,8 @@ def name=(v) @album = Album.new @album.extend(AlbumRepresenter) - @album.from_json("{\"best_song\":{\"name\":\"Mr. Charisma\"},\"songs\":[{\"name\":\"I Hate My Brain\"},{\"name\":\"Mr. Charisma\"}]}") + @album.from_json('{"best_song":{"name":"Mr. Charisma"},"songs":[{"name":"I Hate My Brain"},{"name":"Mr. Charisma"}]}') + assert_equal "Mr. Charisma", @album.best_song.name end end @@ -176,7 +186,8 @@ class Band end it "#from_json creates correct accessors" do - band = Band.new.from_json({:name => "Bombshell Rocks"}.to_json) + band = Band.new.from_json({name: "Bombshell Rocks"}.to_json) + assert_equal "Bombshell Rocks", band.name end @@ -197,18 +208,21 @@ class Label class Album include Representable::JSON - property :label, :class => Label + property :label, class: Label attr_accessor :label end it "#from_json creates one Item instance" do album = Album.new.from_json('{"label":{"name":"Fat Wreck"}}') + assert_equal "Fat Wreck", album.label.name end it "#to_json serializes" do - label = Label.new; label.name = "Fat Wreck" - album = Album.new; album.label = label + label = Label.new + label.name = "Fat Wreck" + album = Album.new + album.label = label assert_json '{"label":{"name":"Fat Wreck"}}', album.to_json end @@ -217,16 +231,18 @@ class Album before do @Album = Class.new do include Representable::JSON - property :seller, :class => Label + property :seller, class: Label attr_accessor :seller end end it "#to_xml respects the different name" do - label = Label.new; label.name = "Fat Wreck" - album = @Album.new; album.seller = label + label = Label.new + label.name = "Fat Wreck" + album = @Album.new + album.seller = label - assert_json "{\"seller\":{\"name\":\"Fat Wreck\"}}", album.to_json(:wrap => false) + assert_json '{"seller":{"name":"Fat Wreck"}}', album.to_json(wrap: false) end end end @@ -234,17 +250,20 @@ class Album describe ":as => :songName" do class Song include Representable::JSON - property :name, :as => :songName + property :name, as: :songName attr_accessor :name end it "respects :as in #from_json" do - song = Song.new.from_json({:songName => "Run To The Hills"}.to_json) + song = Song.new.from_json({songName: "Run To The Hills"}.to_json) + assert_equal "Run To The Hills", song.name end it "respects :as in #to_json" do - song = Song.new; song.name = "22 Acacia Avenue" + song = Song.new + song.name = "22 Acacia Avenue" + assert_json '{"songName":"22 Acacia Avenue"}', song.to_json end end @@ -259,7 +278,8 @@ class CD end it "#from_json creates correct accessors" do - cd = CD.new.from_json({:songs => ["Out in the cold", "Microphone"]}.to_json) + cd = CD.new.from_json({songs: ["Out in the cold", "Microphone"]}.to_json) + assert_equal ["Out in the cold", "Microphone"], cd.songs end @@ -284,7 +304,7 @@ def initialize(name = "") class Compilation include Representable::JSON - collection :bands, :class => Band + collection :bands, class: Band attr_accessor :bands end @@ -292,12 +312,13 @@ class Compilation it "pushes collection items to array" do cd = Compilation.new.from_json( { - :bands => [ - {:name => "Cobra Skulls"}, - {:name => "Diesel Boy"} + bands: [ + {name: "Cobra Skulls"}, + {name: "Diesel Boy"} ] }.to_json ) + assert_equal ["Cobra Skulls", "Diesel Boy"], cd.bands.map(&:name).sort end end @@ -313,12 +334,13 @@ class Compilation describe ":as => :songList" do class Songs include Representable::JSON - collection :tracks, :as => :songList + collection :tracks, as: :songList attr_accessor :tracks end it "respects :as in #from_json" do - songs = Songs.new.from_json({:songList => ["Out in the cold", "Microphone"]}.to_json) + songs = Songs.new.from_json({songList: ["Out in the cold", "Microphone"]}.to_json) + assert_equal ["Out in the cold", "Microphone"], songs.tracks end @@ -333,44 +355,48 @@ class Songs class HashTest < MiniTest::Spec describe "hash :songs" do - representer!(:module => Representable::JSON) do + representer!(module: Representable::JSON) do hash :songs end subject { OpenStruct.new.extend(representer) } it "renders with #to_json" do - subject.songs = {:one => "65", :two => "Emo Boy"} - assert_json "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}", subject.to_json + subject.songs = {one: "65", two: "Emo Boy"} + + assert_json '{"songs":{"one":"65","two":"Emo Boy"}}', subject.to_json end it "parses with #from_json" do assert_equal( {"one" => "65", "two" => ["Emo Boy"]}, - subject.from_json("{\"songs\":{\"one\":\"65\",\"two\":[\"Emo Boy\"]}}").songs + subject.from_json('{"songs":{"one":"65","two":["Emo Boy"]}}').songs ) end end describe "hash :songs, :class => Song" do - representer!(:module => Representable::JSON) do - hash :songs, :extend => Module.new { include Representable::JSON; property :name }, :class => Song + representer!(module: Representable::JSON) do + hash :songs, extend: Module.new { + include Representable::JSON + property :name + }, class: Song end it "renders" do - _(OpenStruct.new(:songs => {"7" => Song.new("Contemplation")}).extend(representer).to_hash).must_equal("songs"=>{"7"=>{"name"=>"Contemplation"}}) + _(OpenStruct.new(songs: {"7" => Song.new("Contemplation")}).extend(representer).to_hash).must_equal("songs" => {"7" => {"name" => "Contemplation"}}) end describe "parsing" do subject { OpenStruct.new.extend(representer) } - let(:hsh) { {"7"=>{"name"=>"Contemplation"}} } + let(:hsh) { {"7" => {"name" => "Contemplation"}} } it "parses incoming hash" do - _(subject.from_hash("songs"=>hsh).songs).must_equal({"7"=>Song.new("Contemplation")}) + _(subject.from_hash("songs" => hsh).songs).must_equal({"7" => Song.new("Contemplation")}) end it "doesn't modify the incoming hash" do - subject.from_hash("songs"=> incoming_hash = hsh.dup) + subject.from_hash("songs" => incoming_hash = hsh.dup) _(hsh).must_equal incoming_hash end end diff --git a/test/lonely_test.rb b/test/lonely_test.rb index d49a5c4b..105806fb 100644 --- a/test/lonely_test.rb +++ b/test/lonely_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" require "representable/json/hash" @@ -5,9 +7,9 @@ class LonelyRepresenterTest < MiniTest::Spec # test ::items without arguments, render-only. for_formats( - :hash => [Representable::Hash::Collection, [{"name"=>"Resist Stance"}, {"name"=>"Suffer"}]], - :json => [Representable::JSON::Collection, "[{\"name\":\"Resist Stance\"},{\"name\":\"Suffer\"}]"], - :xml => [ + hash: [Representable::Hash::Collection, [{"name" => "Resist Stance"}, {"name" => "Suffer"}]], + json: [Representable::JSON::Collection, '[{"name":"Resist Stance"},{"name":"Suffer"}]'], + xml: [ Representable::XML::Collection, "Resist StanceSuffer" ] @@ -24,7 +26,7 @@ class LonelyRepresenterTest < MiniTest::Spec let(:album) { [Song.new("Resist Stance"), Song.new("Suffer")].extend(representer) } it "calls #to_hash on song instances, nothing else" do - render(album).must_equal_document(output) + assert_equal_document(render(album), output) end end end @@ -35,7 +37,13 @@ module SongRepresenter property :name end - let(:decorator) { rpr = representer; Class.new(Representable::Decorator) { include Representable::Hash; include rpr } } + let(:decorator) do + rpr = representer + Class.new(Representable::Decorator) do + include Representable::Hash + include rpr + end + end describe "JSON::Collection" do let(:songs) { [Song.new("Days Go By"), Song.new("Can't Take Them All")] } @@ -45,7 +53,7 @@ module SongRepresenter let(:representer) do Module.new do include Representable::JSON::Collection - items :class => Song, :extend => SongRepresenter + items class: Song, extend: SongRepresenter end end @@ -67,8 +75,8 @@ module SongRepresenter end describe "with inline representer" do - representer!(:module => Representable::JSON::Collection) do - items :class => Song do + representer!(module: Representable::JSON::Collection) do + items class: Song do property :name end end @@ -117,7 +125,7 @@ def to_hash(*); "Two: #{represented}"; end let(:representer) do Module.new do include Representable::JSON::Hash - values :class => Song, :extend => SongRepresenter + values class: Song, extend: SongRepresenter end end let(:json) { "{\"one\":{\"name\":\"Days Go By\"},\"two\":{\"name\":\"Can't Take Them All\"}}" } @@ -135,17 +143,17 @@ def to_hash(*); "Two: #{represented}"; end it "respects :exclude" do assert_json "{\"two\":{\"name\":\"Can't Take Them All\"}}", { - :one => Song.new("Days Go By"), - :two => Song.new("Can't Take Them All") - }.extend(representer).to_json(:exclude => [:one]) + one: Song.new("Days Go By"), + two: Song.new("Can't Take Them All") + }.extend(representer).to_json(exclude: [:one]) end it "respects :include" do assert_json "{\"two\":{\"name\":\"Can't Take Them All\"}}", { - :one => Song.new("Days Go By"), - :two => Song.new("Can't Take Them All") - }.extend(representer).to_json(:include => [:two]) + one: Song.new("Days Go By"), + two: Song.new("Can't Take Them All") + }.extend(representer).to_json(include: [:two]) end end @@ -159,17 +167,20 @@ def to_hash(*); "Two: #{represented}"; end end it "respects :exclude" do - assert_equal({"two" => Song.new("Can't Take Them All")}, {}.extend(representer).from_json(json, :exclude => [:one])) + assert_equal( + {"two" => Song.new("Can't Take Them All")}, + {}.extend(representer).from_json(json, exclude: [:one]) + ) end it "respects :include" do - assert_equal({"one" => Song.new("Days Go By")}, {}.extend(representer).from_json(json, :include => [:one])) + assert_equal({"one" => Song.new("Days Go By")}, {}.extend(representer).from_json(json, include: [:one])) end end describe "with inline representer" do - representer!(:module => Representable::JSON::Hash) do - values :class => Song do + representer!(module: Representable::JSON::Hash) do + values class: Song do property :name end end @@ -185,11 +196,11 @@ def to_hash(*); "Two: #{represented}"; end include Representable::JSON::Hash end end - let(:json) { %{{"one":1,"two":2}} } + let(:json) { %({"one":1,"two":2}) } let(:data) { {one: 2, two: 3} } describe "#to_json" do - it { _(data.extend(representer).to_json).must_equal %{{"one":2,"two":3}} } + it { _(data.extend(representer).to_json).must_equal %({"one":2,"two":3}) } # it "respects :exclude" do # assert_json "{\"two\":{\"name\":\"Can't Take Them All\"}}", {:one => Song.new("Days Go By"), :two => Song.new("Can't Take Them All")}.extend(representer).to_json(:exclude => [:one]) @@ -237,5 +248,5 @@ class CollectionWithIncludeTest < MiniTest::Spec end it { _(representer.new([Song.new(1, "ACAB")]).to_hash).must_equal([{"id" => 1, "title" => "ACAB"}]) } - it { _(representer.new([Song.new(1, "ACAB")]).to_hash(include: [:title])).must_equal([{"title"=>"ACAB"}]) } + it { _(representer.new([Song.new(1, "ACAB")]).to_hash(include: [:title])).must_equal([{"title" => "ACAB"}]) } end diff --git a/test/models/album.rb b/test/models/album.rb new file mode 100644 index 00000000..8ad1f25f --- /dev/null +++ b/test/models/album.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class Album + attr_accessor :songs, :best_song + + def initialize(songs = nil, best_song = nil) + @songs = songs + @best_song = best_song + end + + def ==(other) + songs == other.songs and best_song == other.best_song + end +end diff --git a/test/models/band.rb b/test/models/band.rb new file mode 100644 index 00000000..8c84dbab --- /dev/null +++ b/test/models/band.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +Band = Struct.new(:id, :name) do + def [](*attrs) + attrs.collect { |attr| send(attr) } + end +end diff --git a/test/models/song.rb b/test/models/song.rb new file mode 100644 index 00000000..27e2c1bc --- /dev/null +++ b/test/models/song.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class Song + attr_accessor :name, :track # never change this, track rendered with Rails#to_json. + + def initialize(name = nil, track = nil) + @name = name + @track = track + end + + def ==(other) + name == other.name and track == other.track + end +end diff --git a/test/nested_test.rb b/test/nested_test.rb index 0c55e3b3..a16ea81f 100644 --- a/test/nested_test.rb +++ b/test/nested_test.rb @@ -1,21 +1,26 @@ +# frozen_string_literal: true + require "test_helper" class NestedTest < MiniTest::Spec Album = Struct.new(:label, :owner, :amount) for_formats( - :hash => [ + hash: [ Representable::Hash, - {"label" => {"label" => "Epitaph", "owner" => "Brett Gurewitz", "releases" => {"amount"=>19}}} + {"label" => {"label" => "Epitaph", "owner" => "Brett Gurewitz", "releases" => {"amount" => 19}}} ], # :xml => [Representable::XML, ""], - :yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n releases:\n amount: 19\n"] + yaml: [ + Representable::YAML, + "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n releases:\n amount: 19\n" + ] ) do |format, mod, output, _input| [false, true].each do |is_decorator| describe "::nested with (inline representer|decorator): #{is_decorator}" do let(:format) { format } - representer!(:module => mod, :decorator => is_decorator) do + representer!(module: mod, decorator: is_decorator) do nested :label do property :label property :owner @@ -33,7 +38,7 @@ class NestedTest < MiniTest::Spec let(:decorator) { representer.prepare(album) } it "renders nested Album-properties in separate section" do - render(decorator).must_equal_document output + assert_equal_document(render(decorator), output) # do not use extend on the nested object. # FIXME: make this a proper test with two describes instead of this pseudo-meta stuff. _(album).wont_be_kind_of(Representable::Hash) if is_decorator == true @@ -50,7 +55,7 @@ class NestedTest < MiniTest::Spec describe "Decorator ::nested with extend:" do let(:format) { format } - representer!(:name => :label_rpr) do + representer!(name: :label_rpr) do include mod property :label property :owner @@ -60,8 +65,8 @@ class NestedTest < MiniTest::Spec end end - representer!(:module => mod, :decorator => true, :inject => :label_rpr) do - nested :label, :extend => label_rpr + representer!(module: mod, decorator: true, inject: :label_rpr) do + nested :label, extend: label_rpr self.representation_wrap = :album if format == :xml end @@ -70,7 +75,7 @@ class NestedTest < MiniTest::Spec # TODO: shared example with above. it "renders nested Album-properties in separate section" do - render(album).must_equal_document output + assert_equal_document(render(album), output) end it "parses nested properties to Album instance" do @@ -83,7 +88,7 @@ class NestedTest < MiniTest::Spec end describe "::nested without block but with inherit:" do - representer!(:name => :parent) do + representer!(name: :parent) do include Representable::Hash nested :label do @@ -91,15 +96,15 @@ class NestedTest < MiniTest::Spec end end - representer!(:module => Representable::Hash, :inject => :parent) do + representer!(module: Representable::Hash, inject: :parent) do include parent - nested :label, :inherit => true, :as => "Label" + nested :label, inherit: true, as: "Label" end let(:album) { representer.prepare(Album.new("Epitaph", "Brett Gurewitz", 19)) } it "renders nested Album-properties in separate section" do - _(representer.prepare(album).to_hash).must_equal({"Label"=>{"owner"=>"Brett Gurewitz"}}) + _(representer.prepare(album).to_hash).must_equal({"Label" => {"owner" => "Brett Gurewitz"}}) end # it "parses nested properties to Album instance" do diff --git a/test/object_test.rb b/test/object_test.rb index d7908427..a2555b36 100644 --- a/test/object_test.rb +++ b/test/object_test.rb @@ -8,10 +8,16 @@ class ObjectTest < MiniTest::Spec representer!(module: Representable::Object) do property :title - property :album, instance: ->(options) { options[:fragment].name.upcase!; options[:fragment] } do + property :album, instance: ->(options) { + options[:fragment].name.upcase! + options[:fragment] + } do property :name - collection :songs, instance: ->(options) { options[:fragment].title.upcase!; options[:fragment] } do + collection :songs, instance: ->(options) { + options[:fragment].title.upcase! + options[:fragment] + } do property :title end end @@ -42,10 +48,16 @@ class ObjectTest < MiniTest::Spec representer!(module: Representable::Object) do property :title - property :album, render_filter: ->(input, _options) { input.name = "Live"; input } do + property :album, render_filter: ->(input, _options) { + input.name = "Live" + input + } do property :name - collection :songs, render_filter: ->(input, _options) { input[0].title = 1; input } do + collection :songs, render_filter: ->(input, _options) { + input[0].title = 1 + input + } do property :title end end diff --git a/test/option_test.rb b/test/option_test.rb index 0d9925d2..b34d55a9 100644 --- a/test/option_test.rb +++ b/test/option_test.rb @@ -5,7 +5,7 @@ class OptionTest < MiniTest::Spec class Callable include Uber::Callable - def call(*); "callable" end + def call(*); "callable"; end end class MyRepresenter < Representable::Decorator @@ -27,9 +27,9 @@ def symbol(*); "symbol" end it "supports all types of callables (method, proc, static etc)" do _(album_representer.to_hash).must_equal( { - "static" => "static", - "symbol" => "symbol", - "proc" => "proc", + "static" => "static", + "symbol" => "symbol", + "proc" => "proc", "callable" => "callable" } ) diff --git a/test/parse_pipeline_test.rb b/test/parse_pipeline_test.rb index f18a8f89..02a0ce44 100644 --- a/test/parse_pipeline_test.rb +++ b/test/parse_pipeline_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class ParsePipelineTest < MiniTest::Spec @@ -10,23 +12,23 @@ class ParsePipelineTest < MiniTest::Spec collection :songs, parse_pipeline: ->(*) { Representable::Pipeline.insert( - parse_functions, # original function list from Binding#parse_functions. + parse_functions, # original function list from Binding#parse_functions. ->(input, _options) { input.nil? ? [] : input }, # your new function (can be any callable object).. replace: Representable::OverwriteOnNil # ..that replaces the original function. ) }, - class: Song do + class: Song do property :title end end it do - representer.new(album = Album.new).from_hash("songs"=>nil) + representer.new(album = Album.new).from_hash("songs" => nil) _(album.songs).must_equal [] end it do - representer.new(album = Album.new).from_hash("songs"=>[{"title" => "Business Conduct"}]) + representer.new(album = Album.new).from_hash("songs" => [{"title" => "Business Conduct"}]) _(album.songs).must_equal [Song.new("Business Conduct")] end end @@ -59,8 +61,8 @@ def songs=(array) album = Album.new Representer.new(album).from_hash( { - "artist" => {"email"=>"yo"}, - "songs" => [{"title"=>"Affliction"}, {"title"=>"Dream Beater"}] + "artist" => {"email" => "yo"}, + "songs" => [{"title" => "Affliction"}, {"title" => "Dream Beater"}] } ) _(album.songs).must_equal([Song.new("Affliction"), Song.new("Dream Beater")]) diff --git a/test/pipeline_test.rb b/test/pipeline_test.rb index b439bcac..59375919 100644 --- a/test/pipeline_test.rb +++ b/test/pipeline_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class PipelineTest < MiniTest::Spec @@ -23,25 +25,29 @@ class PipelineTest < MiniTest::Spec AssignFragment = ->(input, options) { options[:fragment] = input } it "linear" do - _(P[SkipParse, Setter].("doc", {fragment: 1})).must_equal "Setter(doc)" + _(P[SkipParse, Setter].call("doc", {fragment: 1})).must_equal "Setter(doc)" # parse style. - _(P[AssignFragment, SkipParse, CreateObject, Prepare].("Bla", {})).must_equal "Prepare(#)" + _(P[AssignFragment, SkipParse, CreateObject, Prepare].call("Bla", {})).must_equal "Prepare(#)" # render style. - _(P[Getter, StopOnNil, SkipRender, Prepare, Setter].(nil, {})) + _(P[Getter, StopOnNil, SkipRender, Prepare, Setter].call(nil, {})) .must_equal "Setter(Prepare(Yo))" # pipeline = Representable::Pipeline[SkipParse , SetResult, ModifyResult] # pipeline.(fragment: "yo!").must_equal "modified object from yo!" end - Stopping = ->(input, options) { return P::Stop if options[:fragment] == "stop!"; input } + Stopping = ->(input, options) { + return P::Stop if options[:fragment] == "stop!" + + input + } it "stopping" do pipeline = Representable::Pipeline[SkipParse, Stopping, Prepare] - _(pipeline.(nil, fragment: "oy!")).must_equal "Prepare()" - _(pipeline.(nil, fragment: "stop!")).must_equal Representable::Pipeline::Stop + _(pipeline.call(nil, fragment: "oy!")).must_equal "Prepare()" + _(pipeline.call(nil, fragment: "stop!")).must_equal Representable::Pipeline::Stop end describe "Collect" do @@ -49,11 +55,11 @@ class PipelineTest < MiniTest::Spec Add = ->(input, _options) { "#{input}+" } let(:pipeline) { R::Collect[Reverse, Add] } - it { _(pipeline.(["yo!", "oy!"], {})).must_equal ["!oy+", "!yo+"] } + it { _(pipeline.call(["yo!", "oy!"], {})).must_equal ["!oy+", "!yo+"] } describe "Pipeline with Collect" do let(:pipeline) { P[Reverse, R::Collect[Reverse, Add]] } - it { _(pipeline.(["yo!", "oy!"], {})).must_equal ["!yo+", "!oy+"] } + it { _(pipeline.call(["yo!", "oy!"], {})).must_equal ["!yo+", "!oy+"] } end end @@ -73,10 +79,10 @@ class PipelineTest < MiniTest::Spec R::StopOnSkipable, R::AssignName, R::WriteFragment - ].(nil, {represented: Song.new("Lime Green"), binding: title, doc: doc}) + ].call(nil, {represented: Song.new("Lime Green"), binding: title, doc: doc}) ).must_equal "Lime Green" - _(doc).must_equal({"title"=>"Lime Green"}) + _(doc).must_equal({"title" => "Lime Green"}) end it "parsing scalar property" do @@ -88,10 +94,10 @@ class PipelineTest < MiniTest::Spec R::OverwriteOnNil, # R::SkipParse, R::SetValue, - ].extend(P::Debug).(doc = {"title"=>"Eruption"}, { - represented: song = Song.new("Lime Green"), binding: title, - doc: doc - }) + ].extend(P::Debug).call(doc = {"title" => "Eruption"}, { + represented: song = Song.new("Lime Green"), binding: title, + doc: doc + }) ).must_equal "Eruption" _(song.title).must_equal "Eruption" end @@ -120,13 +126,13 @@ module ArtistRepresenter R::Serialize, R::AssignName, R::WriteFragment - ].extend(P::Debug).(nil, { - represented: song_model, binding: artist, doc: doc, - options: {} - }) + ].extend(P::Debug).call(nil, { + represented: song_model, binding: artist, doc: doc, + options: {} + }) ).must_equal({"name" => "Diesel Boy"}) - _(doc).must_equal({"artist"=>{"name"=>"Diesel Boy"}}) + _(doc).must_equal({"artist" => {"name" => "Diesel Boy"}}) end it "parsing typed property" do @@ -141,10 +147,10 @@ module ArtistRepresenter R::Decorate, R::Deserialize, R::SetValue, - ].extend(P::Debug).(doc = {"artist"=>{"name"=>"Doobie Brothers"}}, { - represented: song_model, binding: artist, doc: doc, - options: {} - }) + ].extend(P::Debug).call(doc = {"artist" => {"name" => "Doobie Brothers"}}, { + represented: song_model, binding: artist, doc: doc, + options: {} + }) ).must_equal model = Artist.new("Doobie Brothers") _(song_model.artist).must_equal model end @@ -167,10 +173,10 @@ module ArtistRepresenter ], R::AssignName, R::WriteFragment - ].extend(P::Debug).(nil, {represented: Album.new([1, 2, 3]), binding: ratings, doc: doc, options: {}}) + ].extend(P::Debug).call(nil, {represented: Album.new([1, 2, 3]), binding: ratings, doc: doc, options: {}}) ).must_equal([1, 2, 3]) - _(doc).must_equal({"ratings"=>[1, 2, 3]}) + _(doc).must_equal({"ratings" => [1, 2, 3]}) end ######### collection :songs, extend: SongRepresenter @@ -191,19 +197,19 @@ module ArtistRepresenter ], R::AssignName, R::WriteFragment - ].extend(P::Debug).(nil, { - represented: Album.new(nil, [Artist.new("Diesel Boy"), Artist.new("Van Halen")]), binding: artists, - doc: doc, options: {} - }) - ).must_equal([{"name"=>"Diesel Boy"}, {"name"=>"Van Halen"}]) + ].extend(P::Debug).call(nil, { + represented: Album.new(nil, [Artist.new("Diesel Boy"), Artist.new("Van Halen")]), binding: artists, + doc: doc, options: {} + }) + ).must_equal([{"name" => "Diesel Boy"}, {"name" => "Van Halen"}]) - _(doc).must_equal({"artists"=>[{"name"=>"Diesel Boy"}, {"name"=>"Van Halen"}]}) + _(doc).must_equal({"artists" => [{"name" => "Diesel Boy"}, {"name" => "Van Halen"}]}) end let(:album_model) { Album.new(nil, [Artist.new("Diesel Boy"), Artist.new("Van Halen")]) } it "parse typed collection" do - doc = {"artists"=>[{"name"=>"Diesel Boy"}, {"name"=>"Van Halen"}]} + doc = {"artists" => [{"name" => "Diesel Boy"}, {"name" => "Van Halen"}]} _( P[ R::AssignName, @@ -218,10 +224,10 @@ module ArtistRepresenter R::Deserialize, ], R::SetValue, - ].extend(P::Debug).(doc, { - represented: album_model, binding: artists, doc: doc, - options: {} - }) + ].extend(P::Debug).call(doc, { + represented: album_model, binding: artists, doc: doc, + options: {} + }) ).must_equal([Artist.new("Diesel Boy"), Artist.new("Van Halen")]) _(album_model.artists).must_equal([Artist.new("Diesel Boy"), Artist.new("Van Halen")]) @@ -232,23 +238,33 @@ module ArtistRepresenter let(:pipeline) { P[R::GetValue, R::StopOnSkipable, R::StopOnNil] } it "returns Pipeline instance when passing in Pipeline instance" do - _(P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable)).must_be_instance_of(R::Pipeline) + _(P::Insert.call(pipeline, R::Default, replace: R::StopOnSkipable)).must_be_instance_of(R::Pipeline) end it "replaces if exists" do # pipeline.insert!(R::Default, replace: R::StopOnSkipable) - _(P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable)).must_equal P[R::GetValue, R::Default, R::StopOnNil] + _( + P::Insert.call( + pipeline, R::Default, + replace: R::StopOnSkipable + ) + ).must_equal P[R::GetValue, R::Default, R::StopOnNil] _(pipeline).must_equal P[R::GetValue, R::StopOnSkipable, R::StopOnNil] end it "replaces Function instance" do pipeline = P[R::Prepare, R::StopOnSkipable, R::StopOnNil] - _(P::Insert.(pipeline, R::Default, replace: R::Prepare)).must_equal P[R::Default, R::StopOnSkipable, R::StopOnNil] + _( + P::Insert.call( + pipeline, R::Default, + replace: R::Prepare + ) + ).must_equal P[R::Default, R::StopOnSkipable, R::StopOnNil] _(pipeline).must_equal P[R::Prepare, R::StopOnSkipable, R::StopOnNil] end it "does not replace when not existing" do - P::Insert.(pipeline, R::Default, replace: R::Prepare) + P::Insert.call(pipeline, R::Default, replace: R::Prepare) _(pipeline).must_equal P[R::GetValue, R::StopOnSkipable, R::StopOnNil] end @@ -256,18 +272,12 @@ module ArtistRepresenter pipeline = P[R::GetValue, R::Collect[R::GetValue, R::StopOnSkipable], R::StopOnNil] _( - P::Insert.( - pipeline, R::Default, - replace: R::StopOnSkipable - ).extend(P::Debug).inspect + P::Insert.call(pipeline, R::Default, replace: R::StopOnSkipable).extend(P::Debug).inspect ).must_equal "Pipeline[GetValue, Collect[GetValue, Default], StopOnNil]" _(pipeline).must_equal P[R::GetValue, R::Collect[R::GetValue, R::StopOnSkipable], R::StopOnNil] _( - P::Insert.( - pipeline, R::Default, - replace: R::StopOnNil - ).extend(P::Debug).inspect + P::Insert.call(pipeline, R::Default, replace: R::StopOnNil).extend(P::Debug).inspect ).must_equal "Pipeline[GetValue, Collect[GetValue, StopOnSkipable], Default]" end @@ -275,10 +285,7 @@ module ArtistRepresenter pipeline = P[R::GetValue, R::Collect[R::GetValue, R::CreateObject], R::StopOnNil] _( - P::Insert.( - pipeline, R::Default, - replace: R::CreateObject - ).extend(P::Debug).inspect + P::Insert.call(pipeline, R::Default, replace: R::CreateObject).extend(P::Debug).inspect ).must_equal "Pipeline[GetValue, Collect[GetValue, Default], StopOnNil]" _(pipeline).must_equal P[R::GetValue, R::Collect[R::GetValue, R::CreateObject], R::StopOnNil] end @@ -288,7 +295,7 @@ module ArtistRepresenter let(:pipeline) { P[R::GetValue, R::StopOnNil] } it do - _(P::Insert.(pipeline, R::GetValue, delete: true).extend(P::Debug).inspect).must_equal "Pipeline[StopOnNil]" + _(P::Insert.call(pipeline, R::GetValue, delete: true).extend(P::Debug).inspect).must_equal "Pipeline[StopOnNil]" _(pipeline.extend(P::Debug).inspect).must_equal "Pipeline[GetValue, StopOnNil]" end end @@ -298,10 +305,7 @@ module ArtistRepresenter it do _( - P::Insert.( - pipeline, R::GetValue, - delete: true - ).extend(P::Debug).inspect + P::Insert.call(pipeline, R::GetValue, delete: true).extend(P::Debug).inspect ).must_equal "Pipeline[Collect[StopOnSkipable], StopOnNil]" _(pipeline.extend(P::Debug).inspect).must_equal "Pipeline[GetValue, Collect[GetValue, StopOnSkipable], StopOnNil]" end diff --git a/test/populator_test.rb b/test/populator_test.rb index c6138186..eb58c2a6 100644 --- a/test/populator_test.rb +++ b/test/populator_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class PopulatorTest < Minitest::Spec @@ -7,7 +9,10 @@ class PopulatorTest < Minitest::Spec describe "populator: ->{}" do representer! do - collection :songs, populator: ->(_input, options) { options[:represented].songs << song = Song.new; song } do + collection :songs, populator: ->(_input, options) { + options[:represented].songs << song = Song.new + song + } do property :id end @@ -19,8 +24,8 @@ class PopulatorTest < Minitest::Spec let(:album) { Album.new([]) } it do - album.extend(representer).from_hash("songs" => [{"id"=>1}, {"id"=>2}], "artist" => {"name"=>"Waste"}) - _(album.inspect).must_equal "#, #], artist=#>" + album.extend(representer).from_hash("songs" => [{"id" => 1}, {"id" => 2}], "artist" => {"name" => "Waste"}) + _(album.inspect).must_equal '#, #], artist=#>' end end @@ -58,7 +63,7 @@ def song=(v) let(:album) { Composer.new.extend(representer).extend(Representable::Debug) } it "finds by :id and creates new without :id" do - album.from_hash({"song"=>{"id" => 1, "title" => "Resist Stance"}}) + album.from_hash({"song" => {"id" => 1, "title" => "Resist Stance"}}) _(album.song.title).must_equal "Resist Stance" # NOTE: how title is updated from "Resist Stan" _(album.song.id).must_equal 1 @@ -66,7 +71,7 @@ def song=(v) end it "creates new without :id" do - album.from_hash({"song"=>{"title"=>"Lower"}}) + album.from_hash({"song" => {"title" => "Lower"}}) _(album.song.title).must_equal "Lower" _(album.song.id).must_be_nil @@ -89,7 +94,7 @@ def song=(v) { "songs" => [ {"id" => 1, "title" => "Resist Stance"}, - {"title"=>"Suffer"} + {"title" => "Suffer"} ] } ) diff --git a/test/prepare_test.rb b/test/prepare_test.rb index 8f8ad0d3..e3acd9bb 100644 --- a/test/prepare_test.rb +++ b/test/prepare_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class PrepareTest < BaseTest @@ -18,10 +20,10 @@ def ==(other) describe "#to_hash" do # TODO: introduce :representable option? representer! do property :song, - :prepare => ->(options) { options[:binding][:arbitrary].new(options[:input]) }, - :arbitrary => PreparerClass, - :extend => true, - :representable => false # don't call #to_hash. + prepare: ->(options) { options[:binding][:arbitrary].new(options[:input]) }, + arbitrary: PreparerClass, + extend: true, + representable: false # don't call #to_hash. end let(:hit) { Struct.new(:song).new(song).extend(representer) } @@ -44,12 +46,12 @@ def ==(other) describe "#from_hash" do representer! do property :song, - :prepare => ->(options) { options[:binding][:arbitrary].new(options[:input]) }, - :arbitrary => PreparerClass, + prepare: ->(options) { options[:binding][:arbitrary].new(options[:input]) }, + arbitrary: PreparerClass, # :extend => true, # TODO: typed: true would be better. - :instance => String.new, # pass_fragment - :pass_options => true, - :representable => false # don't call #to_hash. + instance: +"", # pass_fragment + pass_options: true, + representable: false # don't call #to_hash. end let(:hit) { Struct.new(:song).new.extend(representer) } @@ -58,7 +60,7 @@ def ==(other) # render(hit).must_equal_document(output) hit.from_hash("song" => {}) - _(hit.song).must_equal(PreparerClass.new(String.new)) + _(hit.song).must_equal(PreparerClass.new((+""))) end end end diff --git a/test/private_options_test.rb b/test/private_options_test.rb index 9f53bf6f..fd9d920d 100644 --- a/test/private_options_test.rb +++ b/test/private_options_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" # TODO: move me to separate file. diff --git a/test/reader_writer_test.rb b/test/reader_writer_test.rb index ce038969..e9922087 100644 --- a/test/reader_writer_test.rb +++ b/test/reader_writer_test.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require "test_helper" class ReaderWriterTest < BaseTest representer! do property :name, - :writer => ->(options) { options[:doc]["title"] = "#{options[:user_options][:nr]}) #{options[:input]}" }, - :reader => ->(options) { self.name = options[:doc]["title"].split(") ").last } + writer: ->(options) { options[:doc]["title"] = "#{options[:user_options][:nr]}) #{options[:input]}" }, + reader: ->(options) { self.name = options[:doc]["title"].split(") ").last } end - subject { OpenStruct.new(:name => "Disorder And Disarray").extend(representer) } + subject { OpenStruct.new(name: "Disorder And Disarray").extend(representer) } it "uses :writer when rendering" do _(subject.to_hash(user_options: {nr: 14})).must_equal({"title" => "14) Disorder And Disarray"}) diff --git a/test/realistic_benchmark.rb b/test/realistic_benchmark.rb index 783371e7..add9ce19 100644 --- a/test/realistic_benchmark.rb +++ b/test/realistic_benchmark.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + require "test_helper" require "benchmark" -SONG_PROPERTIES = 50.times.collect do |i| +SONG_PROPERTIES = Array.new(50) do |i| "song_property_#{i}" end @@ -40,7 +42,7 @@ def random_song times = [] 3.times.each do - album = Album.new(100.times.collect { random_song }) + album = Album.new(Array.new(100) { random_song }) times << Benchmark.measure do puts "================ next!" @@ -48,9 +50,9 @@ def random_song end end -puts times.join("") +puts times.join -album = Album.new(100.times.collect { random_song }) +album = Album.new(Array.new(100) { random_song }) require "ruby-prof" RubyProf.start AlbumRepresenter.new(album).to_hash diff --git a/test/render_nil_test.rb b/test/render_nil_test.rb index c4540875..04a9695b 100644 --- a/test/render_nil_test.rb +++ b/test/render_nil_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class RenderNilTest < MiniTest::Spec @@ -8,7 +10,7 @@ class RenderNilTest < MiniTest::Spec property :title, render_nil: true end - it { _(Song.new.extend(representer).to_hash).must_equal({"title"=>nil}) } + it { _(Song.new.extend(representer).to_hash).must_equal({"title" => nil}) } end describe "with :extend it shouldn't extend nil" do @@ -16,6 +18,6 @@ class RenderNilTest < MiniTest::Spec property :title, render_nil: true, extend: Class end - it { _(Song.new.extend(representer).to_hash).must_equal({"title"=>nil}) } + it { _(Song.new.extend(representer).to_hash).must_equal({"title" => nil}) } end end diff --git a/test/represent_test.rb b/test/represent_test.rb index 47b0c095..4e489ac1 100644 --- a/test/represent_test.rb +++ b/test/represent_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class RepresentTest < MiniTest::Spec @@ -5,7 +7,7 @@ class RepresentTest < MiniTest::Spec let(:song) { Song.new("Days Go By") } for_formats( - :hash => [Representable::Hash, out = [{"name" => "Days Go By"}, {"name"=>"Can't Take Them All"}], out] + hash: [Representable::Hash, out = [{"name" => "Days Go By"}, {"name" => "Can't Take Them All"}], out] # :json => [Representable::JSON, out="[{\"name\":\"Days Go By\"},{\"name\":\"Can't Take Them All\"}]", out], # :xml => [Representable::XML, out="", out] ) do |format, mod, output, input| @@ -18,11 +20,13 @@ class RepresentTest < MiniTest::Spec include mod property :name - collection_representer :class => Song # TODOOOOOOOOOOOO: test without Song and fix THIS FUCKINGNoMethodError: undefined method `name=' for {"name"=>"Days Go By"}:Hash ERROR!!!!!!!!!!!!!!! + collection_representer class: Song # TODOOOOOOOOOOOO: test without Song and fix THIS FUCKINGNoMethodError: undefined method `name=' for {"name"=>"Days Go By"}:Hash ERROR!!!!!!!!!!!!!!! end end - it { render(representer.represent(songs)).must_equal_document output } + it { + assert_equal_document(render(representer.represent(songs)), output) + } it { _(parse(representer.represent([]), input)).must_equal songs } end @@ -34,18 +38,20 @@ class RepresentTest < MiniTest::Spec include mod property :name - collection_representer :class => Song + collection_representer class: Song end end - it { render(representer.represent(songs)).must_equal_document output } + it { + assert_equal_document(render(representer.represent(songs)), output) + } it("ficken") { _(parse(representer.represent([]), input)).must_equal songs } end end for_formats( - :hash => [Representable::Hash, out = {"name" => "Days Go By"}, out], - :json => [Representable::JSON, out = "{\"name\":\"Days Go By\"}", out] + hash: [Representable::Hash, out = {"name" => "Days Go By"}, out], + json: [Representable::JSON, out = '{"name":"Days Go By"}', out] # :xml => [Representable::XML, out="", out] ) do |format, mod, output, input| # Representer.represents detects singular. @@ -57,11 +63,11 @@ class RepresentTest < MiniTest::Spec include mod property :name - collection_representer :class => Song + collection_representer class: Song end end - it { render(representer.represent(song)).must_equal_document output } + it { assert_equal_document(render(representer.represent(song)), output) } it { _(parse(representer.represent(Song.new), input)).must_equal song } end @@ -73,11 +79,11 @@ class RepresentTest < MiniTest::Spec include mod property :name - collection_representer :class => Song + collection_representer class: Song end end - it { render(representer.represent(song)).must_equal_document output } + it { assert_equal_document(render(representer.represent(song)), output) } it { _(parse(representer.represent(Song.new), input)).must_equal song } end end diff --git a/test/representable_test.rb b/test/representable_test.rb index 628579e6..a1e2507b 100644 --- a/test/representable_test.rb +++ b/test/representable_test.rb @@ -36,7 +36,8 @@ module PunkBandRepresentation end.new vd.name = "Vention Dention" vd.street_cred = 1 - assert_json "{\"name\":\"Vention Dention\",\"street_cred\":1}", vd.to_json + + assert_json '{"name":"Vention Dention","street_cred":1}', vd.to_json end # it "allows including the concrete representer module only" do @@ -71,6 +72,7 @@ module CoverSongRepresenter it "merges properties from all ancestors" do props = {"name" => "The Brews", "by" => "Nofx"} + assert_equal(props, CoverSong.new(props).extend(CoverSongRepresenter).to_hash) end @@ -87,14 +89,14 @@ class Bodyjar band = Bodyjar.new band.name = "Bodyjar" - assert_json "{\"band\":{\"name\":\"Bodyjar\"}}", band.to_json + assert_json '{"band":{"name":"Bodyjar"}}', band.to_json assert_xml_equal "Bodyjar", band.to_xml end it "allows extending with different representers subsequentially" do module SongXmlRepresenter include Representable::XML - property :name, :as => "name", :attribute => true + property :name, as: "name", attribute: true end module SongJsonRepresenter @@ -103,8 +105,9 @@ module SongJsonRepresenter end @song = Song.new("Days Go By") - assert_xml_equal "", @song.extend(SongXmlRepresenter).to_xml - assert_json "{\"name\":\"Days Go By\"}", @song.extend(SongJsonRepresenter).to_json + + assert_xml_equal '', @song.extend(SongXmlRepresenter).to_xml + assert_json '{"name":"Days Go By"}', @song.extend(SongJsonRepresenter).to_json end # test if we call super in @@ -185,7 +188,7 @@ class RockBand < Band it "creates correct Definition" do assert_equal "albums", RockBand.representable_attrs.get(:albums).name - assert RockBand.representable_attrs.get(:albums).array? + assert_predicate RockBand.representable_attrs.get(:albums), :array? end end @@ -220,29 +223,38 @@ class PopBand it "copies values from document to object" do @band.from_hash({"name" => "No One's Choice", "groupies" => 2}) + assert_equal "No One's Choice", @band.name assert_equal 2, @band.groupies end it "ignores non-writeable properties" do - @band = Class.new(Band) { property :name; collection :founders, :writeable => false; attr_accessor :founders }.new + @band = Class.new(Band) { + property :name + collection :founders, writeable: false + attr_accessor :founders + }.new @band.from_hash("name" => "Iron Maiden", "groupies" => 2, "founders" => ["Steve Harris"]) + assert_equal "Iron Maiden", @band.name assert_nil @band.founders end it "always returns the represented" do - assert_equal @band, @band.from_hash({"name"=>"Nofx"}) + assert_equal @band, @band.from_hash({"name" => "Nofx"}) end it "includes false attributes" do - @band.from_hash({"groupies"=>false}) + @band.from_hash({"groupies" => false}) + refute @band.groupies end it "ignores properties not present in the incoming document" do @band.instance_eval do - def name=(*); fail "I should never be called!"; end + def name=(*) + fail "I should never be called!" + end end @band.from_hash({}) end @@ -251,7 +263,7 @@ def name=(*); fail "I should never be called!"; end it "ignores (no-default) properties not present in the incoming document" do { Representable::Hash => [:from_hash, {}], - Representable::XML => [:from_xml, xml(%{}).to_s] + Representable::XML => [:from_xml, xml(%{}).to_s] }.each do |format, config| nested_repr = Module.new do # this module is never applied. # FIXME: can we make that a simpler test? include format @@ -260,11 +272,12 @@ def name=(*); fail "I should never be called!"; end repr = Module.new do include format - property :name, :class => Object, :extend => nested_repr + property :name, class: Object, extend: nested_repr end @band = Band.new.extend(repr) @band.send(config.first, config.last) + assert_nil @band.name, "Failed in #{format}" end end @@ -306,17 +319,17 @@ def from_hash(data, options) _( OpenStruct.new( track: OpenStruct.new( - nr: 1, + nr: 1, length: OpenStruct.new(seconds: nil) ) ).extend(representer).extend(Representable::Debug) .to_hash(user_options: {nr: 9}) - ).must_equal({"track"=>{"nr" => 9, "length" => {seconds: 9}}}) + ).must_equal({"track" => {"nr" => 9, "length" => {seconds: 9}}}) end it "#from_hash propagates to nested objects" do song = OpenStruct.new.extend(representer).from_hash( - {"track"=>{"nr" => "replace me", "length" => {"seconds"=>"replacing"}}}, user_options: {nr: 9} + {"track" => {"nr" => "replace me", "length" => {"seconds" => "replacing"}}}, user_options: {nr: 9} ) _(song.track.nr).must_equal 9 _(song.track.length.seconds).must_equal 9 @@ -336,21 +349,28 @@ def from_hash(data, options) end it "ignores non-readable properties" do - @band = Class.new(Band) { property :name; collection :founder_ids, :readable => false; attr_accessor :founder_ids }.new + @band = Class.new(Band) { + property :name + collection :founder_ids, readable: false + attr_accessor :founder_ids + }.new @band.name = "Iron Maiden" @band.founder_ids = [1, 2, 3] hash = @band.to_hash + assert_equal({"name" => "Iron Maiden"}, hash) end it "does not write nil attributes" do @band.groupies = nil - assert_equal({"name"=>"No One's Choice"}, @band.to_hash) + + assert_equal({"name" => "No One's Choice"}, @band.to_hash) end it "writes false attributes" do @band.groupies = false + assert_equal({"name" => "No One's Choice", "groupies" => false}, @band.to_hash) end end @@ -373,26 +393,32 @@ class UpcaseString < String; end describe "lambda blocks" do representer! do - property :name, :extend => ->(name, *) { compute_representer(name) } + property :name, extend: ->(name, *) { compute_representer(name) } end it "executes lambda in represented instance context" do - _( + assert_equal( + {"name" => "CARNAGE"}, Song.new("Carnage").instance_eval { def compute_representer(_name) UpcaseRepresenter end self }.extend(representer).to_hash - ).must_equal({"name" => "CARNAGE"}) + ) end end describe ":instance" do - obj = String.new("Fate") - mod = Module.new { include Representable; def from_hash(*); self; end } + obj = +"Fate" + mod = Module.new do + include Representable + def from_hash(*) + self + end + end representer! do - property :name, :extend => mod, :instance => ->(*) { obj } + property :name, extend: mod, instance: ->(*) { obj } end it "uses object from :instance but still extends it" do @@ -404,14 +430,17 @@ def compute_representer(_name) describe "property with :extend" do representer! do - property :name, :extend => ->(options) { - options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter - }, :class => String + property :name, extend: ->(options) { + options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter + }, class: String end it "uses lambda when rendering" do assert_equal({"name" => "you make me thick"}, Song.new("You Make Me Thick").extend(representer).to_hash) - assert_equal({"name" => "STEPSTRANGER"}, Song.new(UpcaseString.new("Stepstranger")).extend(representer).to_hash) + assert_equal( + {"name" => "STEPSTRANGER"}, + Song.new(UpcaseString.new("Stepstranger")).extend(representer).to_hash + ) end it "uses lambda when parsing" do @@ -421,10 +450,10 @@ def compute_representer(_name) describe "with :class lambda" do representer! do - property :name, :extend => ->(options) { - options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter - }, - :class => ->(options) { options[:fragment] == "Still Failing?" ? String : UpcaseString } + property :name, extend: ->(options) { + options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter + }, + class: ->(options) { options[:fragment] == "Still Failing?" ? String : UpcaseString } end it "creates instance from :class lambda when parsing" do @@ -441,9 +470,9 @@ def compute_representer(_name) describe "collection with :extend" do representer! do - collection :songs, :extend => ->(options) { - options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter - }, :class => String + collection :songs, extend: ->(options) { + options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter + }, class: String end it "uses lambda for each item when rendering" do @@ -461,28 +490,38 @@ def compute_representer(_name) end it "uses lambda for each item when parsing" do - album = Album.new.extend(representer).from_hash("songs"=>["DEAN MARTIN", "charlie still smirks"]) + album = Album.new.extend(representer).from_hash("songs" => ["DEAN MARTIN", "charlie still smirks"]) _(album.songs).must_equal ["dean martin", "charlie still smirks"] # DISCUSS: we compare "".is_a?(UpcaseString) end describe "with :class lambda" do representer! do - collection :songs, :extend => ->(options) { - options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter - }, - :class => ->(options) { options[:input] == "Still Failing?" ? String : UpcaseString } + collection :songs, extend: ->(options) { + options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter + }, + class: ->(options) { options[:input] == "Still Failing?" ? String : UpcaseString } end it "creates instance from :class lambda for each item when parsing" do - album = Album.new.extend(representer).from_hash("songs"=>["Still Failing?", "charlie still smirks"]) + album = Album.new.extend(representer).from_hash("songs" => ["Still Failing?", "charlie still smirks"]) _(album.songs).must_equal ["still failing?", "CHARLIE STILL SMIRKS"] end end end describe ":decorator" do - let(:extend_rpr) { Module.new { include Representable::Hash; collection :songs, :extend => SongRepresenter } } - let(:decorator_rpr) { Module.new { include Representable::Hash; collection :songs, :decorator => SongRepresenter } } + let(:extend_rpr) do + Module.new do + include Representable::Hash + collection :songs, extend: SongRepresenter + end + end + let(:decorator_rpr) do + Module.new do + include Representable::Hash + collection :songs, decorator: SongRepresenter + end + end let(:songs) { [Song.new("Bloody Mary")] } it "is aliased to :extend" do @@ -499,7 +538,7 @@ class SongRepresentation < Representable::Decorator class AlbumRepresentation < Representable::Decorator include Representable::JSON - collection :songs, :class => Song, :extend => SongRepresentation + collection :songs, class: Song, extend: SongRepresentation end describe "::prepare" do @@ -508,16 +547,19 @@ class AlbumRepresentation < Representable::Decorator describe "module including Representable" do it "uses :extend strategy" do - album_rpr = Module.new { include Representable::Hash; collection :songs, :class => Song, :extend => SongRepresenter } + album_rpr = Module.new do + include Representable::Hash + collection :songs, class: Song, extend: SongRepresenter + end - _(album_rpr.prepare(album).to_hash).must_equal({"songs"=>[{"name"=>"Still Friends In The End"}]}) + _(album_rpr.prepare(album).to_hash).must_equal({"songs" => [{"name" => "Still Friends In The End"}]}) _(album).must_respond_to :to_hash end end describe "Decorator subclass" do it "uses :decorate strategy" do - _(AlbumRepresentation.prepare(album).to_hash).must_equal({"songs"=>[{"name"=>"Still Friends In The End"}]}) + _(AlbumRepresentation.prepare(album).to_hash).must_equal({"songs" => [{"name" => "Still Friends In The End"}]}) _(album).wont_respond_to :to_hash end end diff --git a/test/schema_test.rb b/test/schema_test.rb index 79d013ee..78d8088e 100644 --- a/test/schema_test.rb +++ b/test/schema_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" # Include Inherit Module And Decorator Test @@ -33,7 +35,7 @@ module Module end end - property :album, :extend => -> { fail "don't manifest me!" } # this is not an inline decorator, don't manifest it. + property :album, extend: -> { fail "don't manifest me!" } # this is not an inline decorator, don't manifest it. include Genre # Schema::Included::included is called! end @@ -55,13 +57,15 @@ class WithLocationStreetRepresenter < Representable::Decorator end describe "3-level deep with features" do - let(:label) { OpenStruct.new(:name => "Epitaph", :location => OpenStruct.new(:city => "Sanfran", :name => "DON'T SHOW ME!")) } + let(:label) do + OpenStruct.new(name: "Epitaph", location: OpenStruct.new(city: "Sanfran", name: "DON'T SHOW ME!")) + end # Module does correctly include features in inlines. it { _(band.extend(Module).to_hash).must_equal( { - "label" => {"name" => "Epitaph", "location" => {"city"=>"Sanfran"}}, + "label" => {"name" => "Epitaph", "location" => {"city" => "Sanfran"}}, "genre" => "Punkrock" } ) @@ -71,7 +75,7 @@ class WithLocationStreetRepresenter < Representable::Decorator it { _(Decorator.new(band).to_hash).must_equal( { - "label" => {"name" => "Epitaph", "location" => {"city"=>"Sanfran"}}, + "label" => {"name" => "Epitaph", "location" => {"city" => "Sanfran"}}, "genre" => "Punkrock" } ) @@ -88,11 +92,11 @@ class Decorator < Representable::Decorator let(:label) do OpenStruct.new( - :name => "Fat Wreck", :city => "San Francisco", :employees => [OpenStruct.new(:name => "Mike")], - :location => OpenStruct.new(:city => "Sanfran") + name: "Fat Wreck", city: "San Francisco", employees: [OpenStruct.new(name: "Mike")], + location: OpenStruct.new(city: "Sanfran") ) end - let(:band) { OpenStruct.new(:genre => "Punkrock", :label => label) } + let(:band) { OpenStruct.new(genre: "Punkrock", label: label) } # it { FlatlinersDecorator.new( OpenStruct.new(label: OpenStruct.new) ). # to_hash.must_equal({}) } @@ -100,7 +104,7 @@ class Decorator < Representable::Decorator _(Decorator.new(band).to_hash).must_equal( { "genre" => "Punkrock", - "label" => {"name" => "Fat Wreck", "location" => {"city"=>"Sanfran"}} + "label" => {"name" => "Fat Wreck", "location" => {"city" => "Sanfran"}} } ) end @@ -113,7 +117,7 @@ class InheritDecorator < Representable::Decorator property :label, inherit: true do # decorator.rb:27:in `initialize': superclass must be a Class (Module given) property :city - property :location, :inherit => true do + property :location, inherit: true do property :city end end @@ -125,7 +129,7 @@ class InheritDecorator < Representable::Decorator "genre" => "Punkrock", "label" => { "name" => "Fat Wreck", "city" => "San Francisco", -"location" => {"city"=>"Sanfran"} + "location" => {"city" => "Sanfran"} } } ) @@ -144,8 +148,8 @@ class InheritFromDecorator < InheritDecorator { "genre" => "Punkrock", "label" => { - "name" => "Fat Wreck", "city" => "San Francisco", "employees" => [{"name"=>"Mike"}], - "location" => {"city"=>"Sanfran"} + "name" => "Fat Wreck", "city" => "San Francisco", "employees" => [{"name" => "Mike"}], + "location" => {"city" => "Sanfran"} } } ) diff --git a/test/serialize_deserialize_test.rb b/test/serialize_deserialize_test.rb index d82caf0b..ddef3075 100644 --- a/test/serialize_deserialize_test.rb +++ b/test/serialize_deserialize_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class SerializeDeserializeTest < BaseTest @@ -6,28 +8,35 @@ class SerializeDeserializeTest < BaseTest describe "deserialize" do representer! do property :song, - :instance => ->(options) { options[:input].to_s.upcase }, - :prepare => ->(options) { options[:input] }, - :deserialize => ->(options) { + instance: ->(options) { options[:input].to_s.upcase }, + prepare: ->(options) { options[:input] }, + deserialize: ->(options) { "#{options[:input]} #{options[:fragment]} #{options[:user_options].inspect}" } end - it { _(subject.from_hash({"song" => Object}, user_options: {volume: 9}).song).must_equal "OBJECT Object {:volume=>9}" } + it { + _( + subject.from_hash( + {"song" => Object}, + user_options: {volume: 9} + ).song + ).must_equal "OBJECT Object {:volume=>9}" + } end describe "serialize" do representer! do property :song, - :representable => true, - :prepare => ->(options) { options[:fragment] }, - :serialize => ->(options) { + representable: true, + prepare: ->(options) { options[:fragment] }, + serialize: ->(options) { "#{options[:input]} #{options[:user_options].inspect}" } end before { subject.song = "Arrested In Shanghai" } - it { _(subject.to_hash(user_options: {volume: 9})).must_equal({"song"=>"Arrested In Shanghai {:volume=>9}"}) } + it { _(subject.to_hash(user_options: {volume: 9})).must_equal({"song" => "Arrested In Shanghai {:volume=>9}"}) } end end diff --git a/test/skip_test.rb b/test/skip_test.rb index 46d92211..8d249ea4 100644 --- a/test/skip_test.rb +++ b/test/skip_test.rb @@ -1,10 +1,14 @@ +# frozen_string_literal: true + require "test_helper" class SkipParseTest < MiniTest::Spec representer! do property :title, skip_parse: ->(options) { options[:user_options][:skip?] and options[:fragment] == "skip me" } property :band, - skip_parse: ->(options) { options[:user_options][:skip?] and options[:fragment]["name"].nil? }, class: OpenStruct do + skip_parse: ->(options) { + options[:user_options][:skip?] and options[:fragment]["name"].nil? + }, class: OpenStruct do property :name end @@ -22,8 +26,8 @@ class SkipParseTest < MiniTest::Spec it do song.from_hash( { - "title" => "Victim Of Fate", - "band" => {"name" => "Mute 98"}, + "title" => "Victim Of Fate", + "band" => {"name" => "Mute 98"}, "airplays" => [{"station" => "JJJ"}] }, user_options: {skip?: true} ) @@ -39,8 +43,8 @@ class SkipParseTest < MiniTest::Spec it do song.from_hash( { - "title" => "skip me", - "band" => {}, + "title" => "skip me", + "band" => {}, "airplays" => [{}, {"station" => "JJJ"}, {}] }, user_options: {skip?: true} ) @@ -60,7 +64,9 @@ class SkipRenderTest < MiniTest::Spec end collection :airplays, - skip_render: ->(options) { options[:user_options][:skip?] and options[:input].station == "Radio Dreyeckland" } do + skip_render: ->(options) { + options[:user_options][:skip?] and options[:input].station == "Radio Dreyeckland" + } do property :station end end @@ -69,14 +75,33 @@ class SkipRenderTest < MiniTest::Spec let(:skip_song) { OpenStruct.new(title: "Time Bomb", band: OpenStruct.new(name: "Rancid")).extend(representer) } # do render. - it { _(song.to_hash(user_options: {skip?: true})).must_equal({"title" => "Black Night", "band" => {"name"=>"Time Again"}}) } + it { + _(song.to_hash(user_options: {skip?: true})).must_equal( + { + "title" => "Black Night", + "band" => {"name" => "Time Again"} + } + ) + } # skip. - it { _(skip_song.to_hash(user_options: {skip?: true})).must_equal({"title"=>"Time Bomb"}) } + it { _(skip_song.to_hash(user_options: {skip?: true})).must_equal({"title" => "Time Bomb"}) } # do render all collection items. it do - song = OpenStruct.new(airplays: [OpenStruct.new(station: "JJJ"), OpenStruct.new(station: "ABC")]).extend(representer) - _(song.to_hash(user_options: {skip?: true})).must_equal({"airplays"=>[{"station"=>"JJJ"}, {"station"=>"ABC"}]}) + song = OpenStruct.new( + airplays: [ + OpenStruct.new(station: "JJJ"), + OpenStruct.new(station: "ABC") + ] + ).extend(representer) + _(song.to_hash(user_options: {skip?: true})).must_equal( + { + "airplays" => [ + {"station" => "JJJ"}, + {"station" => "ABC"} + ] + } + ) end # skip middle item. @@ -87,6 +112,13 @@ class SkipRenderTest < MiniTest::Spec OpenStruct.new(station: "ABC") ] ).extend(representer) - _(song.to_hash(user_options: {skip?: true})).must_equal({"airplays"=>[{"station"=>"JJJ"}, {"station"=>"ABC"}]}) + _(song.to_hash(user_options: {skip?: true})).must_equal( + { + "airplays" => [ + {"station" => "JJJ"}, + {"station" => "ABC"} + ] + } + ) end end diff --git a/test/stringify_hash_test.rb b/test/stringify_hash_test.rb index 3c4c635f..92ddc08c 100644 --- a/test/stringify_hash_test.rb +++ b/test/stringify_hash_test.rb @@ -1,22 +1,24 @@ +# frozen_string_literal: true + require "test_helper" class StringifyHashTest < MiniTest::Spec describe "#from_hash" do - representer!(:name => :song_representer) do + representer!(name: :song_representer) do include Representable::Hash include Representable::Hash::AllowSymbols property :title end - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do include Representable::Hash::AllowSymbols - property :song, :extend => song_representer, :class => OpenStruct + property :song, extend: song_representer, class: OpenStruct end it "parses symbols, too" do - _(OpenStruct.new.extend(representer).from_hash({:song => {:title => "Der Optimist"}}).song.title).must_equal "Der Optimist" + _(OpenStruct.new.extend(representer).from_hash({song: {title: "Der Optimist"}}).song.title).must_equal "Der Optimist" end it "still parses strings" do @@ -24,15 +26,15 @@ class StringifyHashTest < MiniTest::Spec end describe "with :wrap" do - representer!(:inject => :song_representer) do + representer!(inject: :song_representer) do include Representable::Hash::AllowSymbols self.representation_wrap = :album - property :song, :extend => song_representer, :class => OpenStruct + property :song, extend: song_representer, class: OpenStruct end it "parses symbols, too" do - _(OpenStruct.new.extend(representer).from_hash({:album => {:song => {:title => "Der Optimist"}}}).song.title).must_equal "Der Optimist" + _(OpenStruct.new.extend(representer).from_hash({album: {song: {title: "Der Optimist"}}}).song.title).must_equal "Der Optimist" end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 73fdce69..5ce9b78a 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,4 +1,9 @@ -require "pry-byebug" +# frozen_string_literal: true + +begin + require "pry-byebug" +rescue LoadError +end require "representable" require "minitest/autorun" @@ -7,39 +12,19 @@ require "representable/debug" require "minitest/assertions" -module MiniTest::Assertions - def assert_equal_xml(text, subject) - assert_equal text.gsub("\n", "").gsub(/(\s\s+)/, ""), subject.gsub("\n", "").gsub(/(\s\s+)/, "") +module MiniTest + module Assertions + def assert_equal_xml(text, subject) + assert_equal text.delete("\n").gsub(/(\s\s+)/, ""), subject.delete("\n").gsub(/(\s\s+)/, "") + end end end String.infect_an_assertion :assert_equal_xml, :must_xml -# TODO: delete all that in 4.0: -class Album - attr_accessor :songs, :best_song - - def initialize(songs = nil, best_song = nil) - @songs = songs - @best_song = best_song - end - - def ==(other) - songs == other.songs and best_song == other.best_song - end -end - -class Song - attr_accessor :name, :track # never change this, track rendered with Rails#to_json. - - def initialize(name = nil, track = nil) - @name = name - @track = track - end - - def ==(other) - name == other.name and track == other.track - end -end +# TODO: delete all that in 4.0 +require_relative "models/album" +require_relative "models/band" +require_relative "models/song" module XmlHelper def xml(document) @@ -51,100 +36,97 @@ module AssertJson module Assertions def assert_json(expected, actual, msg = nil) msg = message(msg, "") { diff expected, actual } - assert_equal(expected.split("").sort, actual.split("").sort, msg) - end - end -end - -MiniTest::Spec.class_eval do - include AssertJson::Assertions - include XmlHelper - def self.for_formats(formats) - formats.each do |format, cfg| - mod, output, input = cfg - yield format, mod, output, input + assert_equal(expected.chars.sort, actual.chars.sort, msg) end end +end - def render(object, *args) - AssertableDocument.new(object.send("to_#{format}", *args), format) - end +module DocumentAssertions + def assert_equal_document(expected, actual, msg = nil) + msg = message(msg) { diff expected, actual } + return assert_xml_equal(expected, actual) if format == :xml - def parse(object, input, *args) - object.send("from_#{format}", input, *args) + assert_equal(expected, actual, msg) end +end - class AssertableDocument - attr_reader :document +module MiniTest + class Spec + include AssertJson::Assertions + include XmlHelper + include DocumentAssertions - def initialize(document, format) - @document = document - @format = format + def self.for_formats(formats) + formats.each do |format, cfg| + mod, output, input = cfg + yield format, mod, output, input + end end - def must_equal_document(*args) - return document.must_equal_xml(*args) if @format == :xml + def render(obj, *args) + obj.send("to_#{format}", *args) + end - document.must_equal(*args) + def parse(object, input, *args) + object.send("from_#{format}", input, *args) end - end - def self.representer!(options = {}, &block) - fmt = options # we need that so the 2nd call to ::let(within a ::describe) remembers the right format. + def self.representer!(options = {}, &block) + fmt = options # we need that so the 2nd call to ::let(within a ::describe) remembers the right format. - name = options[:name] || :representer - format = options[:module] || Representable::Hash + name = options[:name] || :representer + format = options[:module] || Representable::Hash - let(name) do - mod = options[:decorator] ? Class.new(Representable::Decorator) : Module.new + let(name) do + mod = options[:decorator] ? Class.new(Representable::Decorator) : Module.new - inject_representer(mod, fmt) + inject_representer(mod, fmt) - mod.module_eval do - include format - instance_exec(&block) - end + mod.module_eval do + include format + instance_exec(&block) + end - mod - end + mod + end - undef :inject_representer if method_defined? :inject_representer + undef :inject_representer if method_defined? :inject_representer - def inject_representer(mod, options) - return unless options[:inject] + def inject_representer(mod, options) + return unless options[:inject] - injected_name = options[:inject] - injected = send(injected_name) # song_representer - mod.singleton_class.instance_eval do - define_method(injected_name) { injected } + injected_name = options[:inject] + injected = send(injected_name) # song_representer + mod.singleton_class.instance_eval do + define_method(injected_name) { injected } + end end end - end - module TestMethods - def representer_for(modules = [Representable::Hash], &block) - Module.new do - extend TestMethods - include(*modules) - module_exec(&block) + module TestMethods + def representer_for(modules = [Representable::Hash], &block) + Module.new do + extend TestMethods + include(*modules) + module_exec(&block) + end end - end - alias representer! representer_for + alias representer! representer_for + end + include TestMethods end - include TestMethods end class BaseTest < MiniTest::Spec let(:new_album) { OpenStruct.new.extend(representer) } - let(:album) { OpenStruct.new(:songs => ["Fuck Armageddon"]).extend(representer) } - let(:song) { OpenStruct.new(:title => "Resist Stance") } - let(:song_representer) { Module.new { include Representable::Hash; property :title } } -end - -Band = Struct.new(:id, :name) do - def [](*attrs) - attrs.collect { |attr| send(attr) } + let(:album) { OpenStruct.new(songs: ["Fuck Armageddon"]).extend(representer) } + let(:song) { OpenStruct.new(title: "Resist Stance") } + let(:song_representer) do + Module.new do + include Representable::Hash + property :title + end end end diff --git a/test/test_helper_test.rb b/test/test_helper_test.rb index 091729c8..b8c22eb4 100644 --- a/test/test_helper_test.rb +++ b/test/test_helper_test.rb @@ -1,24 +1,26 @@ +# frozen_string_literal: true + require "test_helper" class TestHelperTest < MiniTest::Spec describe "#assert_json" do it "tests for equality" do - assert_json "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}", "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}" + assert_json '{"songs":{"one":"65","two":"Emo Boy"}}', '{"songs":{"one":"65","two":"Emo Boy"}}' end it "allows different key orders" do - assert_json "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}", "{\"songs\":{\"two\":\"Emo Boy\",\"one\":\"65\"}}" + assert_json '{"songs":{"one":"65","two":"Emo Boy"}}', '{"songs":{"two":"Emo Boy","one":"65"}}' end it "complains when expected hash is subset" do assert_raises MiniTest::Assertion do - assert_json "{\"songs\":{\"one\":\"65\"}}", "{\"songs\":{\"two\":\"Emo Boy\",\"one\":\"65\"}}" + assert_json '{"songs":{"one":"65"}}', '{"songs":{"two":"Emo Boy","one":"65"}}' end end it "complains when source hash is subset" do assert_raises MiniTest::Assertion do - assert_json "{\"songs\":{\"two\":\"Emo Boy\",\"one\":\"65\"}}", "{\"songs\":{\"one\":\"65\"}}" + assert_json '{"songs":{"two":"Emo Boy","one":"65"}}', '{"songs":{"one":"65"}}' end end end diff --git a/test/uncategorized_test.rb b/test/uncategorized_test.rb index 2fe84fc7..f029aaca 100644 --- a/test/uncategorized_test.rb +++ b/test/uncategorized_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class StopWhenIncomingObjectFragmentIsNilTest < MiniTest::Spec @@ -18,8 +20,8 @@ class StopWhenIncomingObjectFragmentIsNilTest < MiniTest::Spec _( representer.new(album).from_hash( { - "id" => 1, - "songs" => [{"title"=>"Walkie Talkie"}] + "id" => 1, + "songs" => [{"title" => "Walkie Talkie"}] } ).songs ).must_equal [Song.new("Walkie Talkie")] @@ -36,18 +38,18 @@ class RenderPipelineOptionTest < MiniTest::Spec NilToNA = ->(input, _options) { input.nil? ? "n/a" : input } representer!(decorator: true) do - property :id, render_pipeline: ->(_input, options) do + property :id, render_pipeline: ->(_input, options) { Representable::Pipeline[*render_functions.insert(2, options[:options][:user_options][:function])] - end + } end - it { _(representer.new(Album.new).to_hash(user_options: {function: NilToNA})).must_equal({"id"=>"n/a"}) } - it { _(representer.new(Album.new(1)).to_hash(user_options: {function: NilToNA})).must_equal({"id"=>1}) } + it { _(representer.new(Album.new).to_hash(user_options: {function: NilToNA})).must_equal({"id" => "n/a"}) } + it { _(representer.new(Album.new(1)).to_hash(user_options: {function: NilToNA})).must_equal({"id" => 1}) } it "is cached" do decorator = representer.new(Album.new) - _(decorator.to_hash(user_options: {function: NilToNA})).must_equal({"id"=>"n/a"}) - _(decorator.to_hash(user_options: {function: nil})).must_equal({"id"=>"n/a"}) # non-sense function is not applied. + _(decorator.to_hash(user_options: {function: NilToNA})).must_equal({"id" => "n/a"}) + _(decorator.to_hash(user_options: {function: nil})).must_equal({"id" => "n/a"}) # non-sense function is not applied. end end @@ -56,17 +58,19 @@ class ParsePipelineOptionTest < MiniTest::Spec NilToNA = ->(input, _options) { input.nil? ? "n/a" : input } representer!(decorator: true) do - property :id, parse_pipeline: ->(_input, options) do + property :id, parse_pipeline: ->(_input, options) { Representable::Pipeline[*parse_functions.insert(3, options[:options][:user_options][:function])].extend(Representable::Pipeline::Debug) - end + } end - it { _(representer.new(Album.new).from_hash({"id"=>nil}, user_options: {function: NilToNA}).id).must_equal "n/a" } - it { _(representer.new(Album.new(1)).to_hash(user_options: {function: NilToNA})).must_equal({"id"=>1}) } + it { + _(representer.new(Album.new).from_hash({"id" => nil}, user_options: {function: NilToNA}).id).must_equal "n/a" + } + it { _(representer.new(Album.new(1)).to_hash(user_options: {function: NilToNA})).must_equal({"id" => 1}) } it "is cached" do decorator = representer.new(Album.new) - _(decorator.from_hash({"id"=>nil}, user_options: {function: NilToNA}).id).must_equal "n/a" - _(decorator.from_hash({"id"=>nil}, user_options: {function: "nonsense"}).id).must_equal "n/a" # non-sense function is not applied. + _(decorator.from_hash({"id" => nil}, user_options: {function: NilToNA}).id).must_equal "n/a" + _(decorator.from_hash({"id" => nil}, user_options: {function: "nonsense"}).id).must_equal "n/a" # non-sense function is not applied. end end diff --git a/test/user_options_test.rb b/test/user_options_test.rb index 457172ce..b90cae03 100644 --- a/test/user_options_test.rb +++ b/test/user_options_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class UserOptionsTest < Minitest::Spec @@ -9,13 +11,15 @@ class UserOptionsTest < Minitest::Spec it { _(Song.new("Run With It").extend(representer).to_hash).must_equal({}) } it { - _(Song.new("Run With It").extend(representer).to_hash(user_options: {visible: true})).must_equal({"title"=>"Run With It"}) + _(Song.new("Run With It").extend(representer).to_hash(user_options: {visible: true})).must_equal({"title" => "Run With It"}) + } + it { + _(Song.new("Run With It").extend(representer).from_hash("title" => "Business Conduct").title).must_equal "Run With It" } - it { _(Song.new("Run With It").extend(representer).from_hash("title"=>"Business Conduct").title).must_equal "Run With It" } it { _( Song.new("Run With It").extend(representer).from_hash( - {"title"=>"Business Conduct"}, + {"title" => "Business Conduct"}, user_options: {visible: true} ).title ).must_equal "Business Conduct" diff --git a/test/wrap_test.rb b/test/wrap_test.rb index 978d655c..fcff2b6b 100644 --- a/test/wrap_test.rb +++ b/test/wrap_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class WrapTest < MiniTest::Spec @@ -16,38 +18,45 @@ class SoftcoreBand < HardcoreBand it "infers a printable class name if set to true" do HardcoreBand.representation_wrap = true + assert_equal "hardcore_band", band.send(:representation_wrap) end it "can be set explicitely" do HardcoreBand.representation_wrap = "breach" + assert_equal "breach", band.send(:representation_wrap) end for_formats( - :hash => [Representable::Hash, {"Blink182"=>{"genre"=>"Pop"}}, {"Blink182"=>{"genre"=>"Poppunk"}}], - :json => [Representable::JSON, "{\"Blink182\":{\"genre\":\"Pop\"}}", "{\"Blink182\":{\"genre\":\"Poppunk\"}}"], - :xml => [Representable::XML, "Pop", "Poppunk"] + hash: [Representable::Hash, {"Blink182" => {"genre" => "Pop"}}, {"Blink182" => {"genre" => "Poppunk"}}], + json: [Representable::JSON, '{"Blink182":{"genre":"Pop"}}', '{"Blink182":{"genre":"Poppunk"}}'], + xml: [ + Representable::XML, "Pop", + "Poppunk" + ] # :yaml => [Representable::YAML, "---\nBlink182:\n"], # TODO: fix YAML. ) do |format, mod, output, input| describe "[#{format}] dynamic wrap" do let(:band) { representer.prepare(Struct.new(:name, :genre).new("Blink", "Pop")) } let(:format) { format } - representer!(:module => mod) do + representer!(module: mod) do self.representation_wrap = ->(number:, **) { "#{name}#{number}" } property :genre end - it { render(band, {:number => 182}).must_equal_document(output) } + it { assert_equal_document(render(band, {number: 182}), output) } - it { _(parse(band, input, {:number => 182}).genre).must_equal "Poppunk" } # TODO: better test. also, xml parses _any_ wrap. + it { + _(parse(band, input, {number: 182}).genre).must_equal "Poppunk" + } # TODO: better test. also, xml parses _any_ wrap. end end end class HashDisableWrapTest < MiniTest::Spec - Band = Struct.new(:name, :label) + Band = Struct.new(:name, :label) Album = Struct.new(:band) Label = Struct.new(:name) @@ -57,7 +66,8 @@ class BandDecorator < Representable::Decorator self.representation_wrap = :bands property :name - property :label do # this should have a wrap! + property :label do + # this should have a wrap! self.representation_wrap = :important property :name end @@ -67,15 +77,15 @@ class BandDecorator < Representable::Decorator # direct, local api. it do - _(band.to_hash).must_equal({"bands" => {"name"=>"Social Distortion"}}) - _(band.to_hash(wrap: false)).must_equal({"name"=>"Social Distortion"}) - _(band.to_hash(wrap: :band)).must_equal(:band=>{"name"=>"Social Distortion"}) + _(band.to_hash).must_equal({"bands" => {"name" => "Social Distortion"}}) + _(band.to_hash(wrap: false)).must_equal({"name" => "Social Distortion"}) + _(band.to_hash(wrap: :band)).must_equal(band: {"name" => "Social Distortion"}) end it do - _(band.from_hash({"bands" => {"name"=>"Social Distortion"}}).name).must_equal "Social Distortion" - _(band.from_hash({"name"=>"Social Distortion"}, wrap: false).name).must_equal "Social Distortion" - _(band.from_hash({band: {"name"=>"Social Distortion"}}, wrap: :band).name).must_equal "Social Distortion" + _(band.from_hash({"bands" => {"name" => "Social Distortion"}}).name).must_equal "Social Distortion" + _(band.from_hash({"name" => "Social Distortion"}, wrap: false).name).must_equal "Social Distortion" + _(band.from_hash({band: {"name" => "Social Distortion"}}, wrap: :band).name).must_equal "Social Distortion" end class AlbumDecorator < Representable::Decorator @@ -94,8 +104,8 @@ class AlbumDecorator < Representable::Decorator { "albums" => { "band" => { - "name" => "Social Distortion", - "label" => {"important"=>{"name"=>"Epitaph"}} + "name" => "Social Distortion", + "label" => {"important" => {"name" => "Epitaph"}} } } } @@ -103,12 +113,12 @@ class AlbumDecorator < Representable::Decorator end it "parses" do - _(album.from_hash({"albums" => {"band" => {"name"=>"Rvivr"}}}).band.name).must_equal "Rvivr" + _(album.from_hash({"albums" => {"band" => {"name" => "Rvivr"}}}).band.name).must_equal "Rvivr" end end class XMLDisableWrapTest < MiniTest::Spec - Band = Struct.new(:name, :label) + Band = Struct.new(:name, :label) Album = Struct.new(:band) Label = Struct.new(:name) @@ -127,8 +137,8 @@ class BandDecorator < Representable::Decorator let(:band) { BandDecorator.prepare(Band.new("Social Distortion")) } it do - band.to_xml.must_equal_xml "Social Distortion" - band.to_xml(wrap: "combo").must_equal_xml "Social Distortion" + assert_xml_equal band.to_xml, "Social Distortion" + assert_xml_equal band.to_xml(wrap: "combo"), "Social Distortion" end class AlbumDecorator < Representable::Decorator @@ -143,16 +153,14 @@ class AlbumDecorator < Representable::Decorator # band has wrap turned of per property definition, however, label still has wrap. it "rendersxx" do - skip - _(album.to_xml).must_equal( - { - "albums" => { - "band" => { - "name" => "Social Distortion", - "label" => {"important"=>{"name"=>"Epitaph"}} - } - } - } + assert_xml_equal( + " + + + Social Distortion + + +", album.to_xml ) end diff --git a/test/xml_bindings_test.rb b/test/xml_bindings_test.rb index 6cbdb5c6..9b2c53b1 100644 --- a/test/xml_bindings_test.rb +++ b/test/xml_bindings_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" require "representable/xml/hash" @@ -22,24 +24,25 @@ class SongWithRepresenter < ::Song describe "AttributeBinding" do describe "with plain text items" do before do - @property = Representable::XML::Binding::Attribute.new(Representable::Definition.new(:name, :attribute => true)) + @property = Representable::XML::Binding::Attribute.new(Representable::Definition.new(:name, attribute: true)) end it "extracts with #read" do - assert_equal "The Gargoyle", @property.read(Nokogiri::XML("").root, "name") + assert_equal "The Gargoyle", @property.read(Nokogiri::XML('').root, "name") end it "inserts with #write" do parent = Nokogiri::XML::Node.new("song", @doc) @property.write(parent, "The Gargoyle", "name") - assert_xml_equal("", parent.to_s) + + assert_xml_equal('', parent.to_s) end end end describe "ContentBinding" do before do - @property = Representable::XML::Binding::Content.new(Representable::Definition.new(:name, :content => true)) + @property = Representable::XML::Binding::Content.new(Representable::Definition.new(:name, content: true)) end it "extracts with #read" do @@ -49,6 +52,7 @@ class SongWithRepresenter < ::Song it "inserts with #write" do parent = Nokogiri::XML::Node.new("song", @doc) @property.write(parent, "The Gargoyle", "song") + assert_xml_equal("The Gargoyle", parent.to_s) end end diff --git a/test/xml_namespace_test.rb b/test/xml_namespace_test.rb index 3c04153b..0885e36b 100644 --- a/test/xml_namespace_test.rb +++ b/test/xml_namespace_test.rb @@ -11,27 +11,27 @@ # 1922-11-26 # 2000-02-12 # -# +# # Peppermint Patty # 1966-08-22 -# bold, brash and tomboyish -# -# +# bold, brash and tomboyish +# +# # Snoopy # 1950-10-04 -# extroverted beagle -# -# +# extroverted beagle +# +# # Schroeder # 1951-05-30 -# brought classical music to the Peanuts strip -# -# -# +# brought classical music to the Peanuts strip +# +# +# # Lucy # 1952-03-03 -# bossy, crabby and selfish -# +# bossy, crabby and selfish +# # # @@ -77,15 +77,15 @@ class Library < Representable::Decorator # default namespace for library it "what" do - Library.new(Model::Library.new(book)).to_xml.must_xml( - + assert_xml_equal( # :simple-xml %{ 666 - } + }, # :simple-xml end + Library.new(Model::Library.new(book)).to_xml ) end end @@ -97,7 +97,9 @@ module Model Character = Struct.new(:name, :born, :qualification) end - let(:book) { Model::Book.new(1, 666, Model::Character.new("Fowler"), [Model::Character.new("Frau Java", 1991, "typed")]) } + let(:book) do + Model::Book.new(1, 666, Model::Character.new("Fowler"), [Model::Character.new("Frau Java", 1991, "typed")]) + end # :map-class class Library < Representable::Decorator @@ -122,34 +124,23 @@ class Library < Representable::Decorator end collection :character, class: Model::Character do - namespace "http://eric.van-der-vlist.com/ns/library" + namespace "http://eric.van-der-vlist.com/ns/person" property :qualification - property :name, namespace: "http://eric.van-der-vlist.com/ns/person" - property :born, namespace: "http://eric.van-der-vlist.com/ns/person" + property :name + property :born end end end # :map-class end it "renders" do - Library.new(Model::Library.new(book)).to_xml.must_xml( + assert_equal( # :map-xml - %{ - - 666 - - Fowler - - - typed - Frau Java - 1991 - - -} + "\n \n 666\n \n Fowler\n \n \n typed\n Frau Java\n 1991\n \n \n", # :map-xml end + Library.new(Model::Library.new(book)).to_xml ) end @@ -165,22 +156,25 @@ class Library < Representable::Decorator Fowler - - typed + + typed Frau Java Mr. Ruby Dr. Elixir 1991 - + } # :parse-call end ) - _(lib.book.inspect).must_equal %{#, character=[#]>} - + # take last line only + xml = lib.book.inspect + expected = "#, character=[#]>" + # In Jruby, the encoding is different, so we need to force it to be the same. + assert_equal(expected, xml.encode(expected.encoding)) # :parse-res - lib.book.character[0].name #=> "Frau Java" + assert_equal "Frau Java", lib.book.character[0].name # :parse-res end end end diff --git a/test/xml_test.rb b/test/xml_test.rb index f8083ade..11612036 100644 --- a/test/xml_test.rb +++ b/test/xml_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class XmlPublicMethodsTest < Minitest::Spec @@ -18,8 +20,8 @@ class BandRepresenter < Representable::Decorator # to_hash let(:band) { Band.new("1", "Rancid") } - it { BandRepresenter.new(band).to_xml.must_equal_xml data } - it { BandRepresenter.new(band).render.must_equal_xml data } + it { assert_xml_equal(BandRepresenter.new(band).to_xml, data) } + it { assert_xml_equal(BandRepresenter.new(band).render, data) } end class XmlTest < MiniTest::Spec @@ -57,6 +59,7 @@ def initialize(name = nil) it "parses XML and assigns properties" do @band.from_xml(@xml) + assert_equal %w[Nofx NOFX], [@band.name, @band.label] end end @@ -70,6 +73,7 @@ def initialize(name = nil) it "parses with xmlns present" do @band.from_xml(@xml) + assert_equal %w[Nofx NOFX], [@band.name, @band.label] end end @@ -82,6 +86,7 @@ def initialize(name = nil) it "receives Nokogiri node and assigns properties" do @band.from_node(@xml) + assert_equal %w[Nofx NOFX], [@band.name, @band.label] end end @@ -95,11 +100,13 @@ def initialize(name = nil) describe "#to_node" do it "returns Nokogiri node" do node = Band.new("Rise Against").to_node + assert_kind_of Nokogiri::XML::Element, node end it "wraps with infered class name per default" do node = Band.new("Rise Against").to_node + assert_xml_equal "Rise Against", node.to_s end @@ -110,26 +117,28 @@ def initialize(name = nil) end klass.representation_wrap = :group + assert_xml_equal "Rise Against", klass.new("Rise Against").to_node.to_s end end describe "XML::Binding#build_for" do it "returns AttributeBinding" do - assert_kind_of XML::Binding::Attribute, XML::Binding.build_for(Def.new(:band, :as => "band", :attribute => true)) + assert_kind_of XML::Binding::Attribute, + XML::Binding.build_for(Def.new(:band, as: "band", attribute: true)) end it "returns Binding" do - assert_kind_of XML::Binding, XML::Binding.build_for(Def.new(:band, :class => Hash)) - assert_kind_of XML::Binding, XML::Binding.build_for(Def.new(:band, :as => :content)) + assert_kind_of XML::Binding, XML::Binding.build_for(Def.new(:band, class: Hash)) + assert_kind_of XML::Binding, XML::Binding.build_for(Def.new(:band, as: :content)) end it "returns CollectionBinding" do - assert_kind_of XML::Binding::Collection, XML::Binding.build_for(Def.new(:band, :collection => true)) + assert_kind_of XML::Binding::Collection, XML::Binding.build_for(Def.new(:band, collection: true)) end it "returns HashBinding" do - assert_kind_of XML::Binding::Hash, XML::Binding.build_for(Def.new(:band, :hash => true)) + assert_kind_of XML::Binding::Hash, XML::Binding.build_for(Def.new(:band, hash: true)) end end @@ -141,8 +150,8 @@ module SongRepresenter module AlbumRepresenter include Representable::XML - property :best_song, :class => Song, :extend => SongRepresenter - collection :songs, :class => Song, :as => :song, :extend => SongRepresenter + property :best_song, class: Song, extend: SongRepresenter + collection :songs, class: Song, as: :song, extend: SongRepresenter end it "allows adding the representer by using #extend" do @@ -161,6 +170,7 @@ def name=(v) end civ.extend(BandRepresenter) + assert_xml_equal "CIV", civ.to_xml end @@ -170,11 +180,11 @@ def name=(v) ) @album.extend(AlbumRepresenter) - @album.to_xml.must_equal_xml " + assert_xml_equal " Mr. Charisma I Hate My Brain Mr. Charisma -" +", @album.to_xml end it "extends contained models when deserializing" do @@ -182,6 +192,7 @@ def name=(v) @album.extend(AlbumRepresenter) @album.from_xml("Mr. CharismaI Hate My BrainMr. Charisma") + assert_equal "Mr. Charisma", @album.best_song.name end end @@ -192,8 +203,8 @@ class AttributesTest < MiniTest::Spec describe ":as => rel, :attribute => true" do class Link include Representable::XML - property :href, :as => "href", :attribute => true - property :title, :as => "title", :attribute => true + property :href, as: "href", attribute: true + property :title, as: "title", attribute: true attr_accessor :href, :title end @@ -203,6 +214,7 @@ class Link } ) + assert_equal "http://apotomo.de", link.href assert_equal "Home, sweet home", link.title end @@ -224,9 +236,9 @@ def serialize_node(parent, _value) end include Representable::XML - property :name, :binding => ->(*args) { - CData.new(*args) - } # getter: lambda { |opt| Nokogiri::XML::CDATA.new(opt[:doc], name) } + property :name, binding: ->(*args) { + CData.new(*args) + } # getter: lambda { |opt| Nokogiri::XML::CDATA.new(opt[:doc], name) } attr_accessor :name def initialize(name = nil) @@ -247,7 +259,7 @@ def initialize(name = nil) module AlbumRepresenter include Representable::XML - property :band, :class => Band + property :band, class: Band end class Album @@ -270,6 +282,7 @@ def initialize(band = nil) } ) + assert_equal "Bad Religion", album.band.name end @@ -325,7 +338,7 @@ class BandRepresenter < Representable::Decorator property :genre, attribute: true end - it { BandRepresenter.new(Band.new("Mute")).to_xml.must_equal_xml %{Mute} } + it { assert_xml_equal(BandRepresenter.new(Band.new("Mute")).to_xml, %{Mute}) } class ManagerRepresenter < Representable::Decorator include Representable::XML @@ -334,14 +347,17 @@ class ManagerRepresenter < Representable::Decorator #- :as with nested property it { - ManagerRepresenter.new( - Manager.new( - Band.new( - "Mute", - "Punkrock" + assert_xml_equal( + %{Mute}, + ManagerRepresenter.new( + Manager.new( + Band.new( + "Mute", + "Punkrock" + ) ) - ) - ).to_xml.must_equal_xml %{Mute} + ).to_xml + ) } end @@ -372,6 +388,7 @@ class CompilationRepresenter < Representable::Decorator } ) + assert_equal ["Cobra Skulls", "Diesel Boy"], cd.bands.map(&:name).sort end end @@ -379,10 +396,12 @@ class CompilationRepresenter < Representable::Decorator it "responds to #to_xml" do cd = Compilation.new([Band.new("Diesel Boy"), Band.new("Bad Religion")]) - CompilationRepresenter.new(cd).to_xml.must_equal_xml %{ + assert_xml_equal( + CompilationRepresenter.new(cd).to_xml, %{ Diesel Boy Bad Religion } + ) end end @@ -390,7 +409,7 @@ class CompilationRepresenter < Representable::Decorator let(:xml_doc) do Module.new do include Representable::XML - collection :songs, :as => :song + collection :songs, as: :song end end @@ -404,6 +423,7 @@ class CompilationRepresenter < Representable::Decorator } ) + assert_equal ["Laundry Basket", "Two Kevins", "Wright and Rong"].sort, album.songs.sort end end @@ -413,7 +433,7 @@ class CompilationRepresenter < Representable::Decorator let(:xml_doc) do Module.new do include Representable::XML - collection :songs, :as => :song, :wrap => :songs + collection :songs, as: :song, wrap: :songs end end @@ -430,6 +450,7 @@ class CompilationRepresenter < Representable::Decorator } ) + assert_equal ["Laundry Basket", "Two Kevins", "Wright and Rong"].sort, album.songs.sort end end @@ -437,6 +458,7 @@ class CompilationRepresenter < Representable::Decorator describe "#to_xml" do it "wraps items" do album.songs = ["Laundry Basket", "Two Kevins", "Wright and Rong"] + assert_xml_equal %{ @@ -459,24 +481,32 @@ module SongRepresenter self.representation_wrap = :song end - let(:decorator) { rpr = representer; Class.new(Representable::Decorator) { include Representable::XML; include rpr } } + let(:decorator) do + rpr = representer + Class.new(Representable::Decorator) do + include Representable::XML + include rpr + end + end describe "XML::Collection" do describe "with contained objects" do - representer!(:module => Representable::XML::Collection) do - items :class => Song, :extend => SongRepresenter + representer!(module: Representable::XML::Collection) do + items class: Song, extend: SongRepresenter self.representation_wrap = :songs end let(:songs) { [Song.new("Days Go By"), Song.new("Can't Take Them All")] } - let(:xml_doc) { "Days Go ByCan't Take Them All" } + let(:xml_doc) do + "Days Go ByCan't Take Them All" + end it "renders array" do - songs.extend(representer).to_xml.must_equal_xml xml_doc + assert_xml_equal(songs.extend(representer).to_xml, xml_doc) end it "renders array with decorator" do - decorator.new(songs).to_xml.must_equal_xml xml_doc + assert_xml_equal(decorator.new(songs).to_xml, xml_doc) end it "parses array" do @@ -490,7 +520,7 @@ module SongRepresenter end describe "XML::AttributeHash" do # TODO: move to HashTest. - representer!(:module => Representable::XML::AttributeHash) do + representer!(module: Representable::XML::AttributeHash) do self.representation_wrap = :songs end @@ -499,19 +529,19 @@ module SongRepresenter describe "#to_xml" do it "renders hash" do - songs.extend(representer).to_xml.must_equal_xml xml_doc + assert_xml_equal(songs.extend(representer).to_xml, xml_doc) end it "respects :exclude" do - assert_xml_equal "", songs.extend(representer).to_xml(:exclude => [:one]) + assert_xml_equal "", songs.extend(representer).to_xml(exclude: [:one]) end it "respects :include" do - assert_xml_equal "", songs.extend(representer).to_xml(:include => [:two]) + assert_xml_equal "", songs.extend(representer).to_xml(include: [:two]) end it "renders hash with decorator" do - decorator.new(songs).to_xml.must_equal_xml xml_doc + assert_xml_equal(decorator.new(songs).to_xml, xml_doc) end end @@ -521,11 +551,11 @@ module SongRepresenter end it "respects :exclude" do - assert_equal({"two" => "Can't Take Them All"}, {}.extend(representer).from_xml(xml_doc, :exclude => [:one])) + assert_equal({"two" => "Can't Take Them All"}, {}.extend(representer).from_xml(xml_doc, exclude: [:one])) end it "respects :include" do - assert_equal({"one" => "Graveyards"}, {}.extend(representer).from_xml(xml_doc, :include => [:one])) + assert_equal({"one" => "Graveyards"}, {}.extend(representer).from_xml(xml_doc, include: [:one])) end it "parses hash with decorator" do @@ -546,7 +576,16 @@ class XmlHashTest < MiniTest::Spec let(:doc) { "The GargoyleBronx" } # to_xml - it { OpenStruct.new(songs: {"first" => "The Gargoyle", "second" => "Bronx"}).extend(representer).to_xml.must_equal_xml(doc) } + it { + assert_xml_equal( + OpenStruct.new( + songs: { + "first" => "The Gargoyle", + "second" => "Bronx" + } + ).extend(representer).to_xml, doc + ) + } # FIXME: this NEVER worked! # it { OpenStruct.new.extend(representer).from_xml(doc).songs.must_equal({"first" => "The Gargoyle", "second" => "Bronx"}) } end @@ -571,12 +610,14 @@ class XmlHashTest < MiniTest::Spec # to_xml it { - OpenStruct.new( - songs: { - "first" => OpenStruct.new(title: "The Gargoyle"), - "second" => OpenStruct.new(title: "Bronx") - } - ).extend(representer).to_xml.must_equal_xml(doc) + assert_xml_equal( + OpenStruct.new( + songs: { + "first" => OpenStruct.new(title: "The Gargoyle"), + "second" => OpenStruct.new(title: "Bronx") + } + ).extend(representer).to_xml, doc + ) } # FIXME: this NEVER worked! # it { OpenStruct.new.extend(representer).from_xml(doc).songs.must_equal({"first" => "The Gargoyle", "second" => "Bronx"}) } diff --git a/test/yaml_test.rb b/test/yaml_test.rb index 35f24c86..0500265e 100644 --- a/test/yaml_test.rb +++ b/test/yaml_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class YamlPublicMethodsTest < Minitest::Spec @@ -58,7 +60,7 @@ def yaml_representer(&block) end it "always renders values into strings" do - _(Album.new.tap { |a| a.best_song = 8675309 }.extend(yaml).to_yaml).must_equal( + _(Album.new.tap { |a| a.best_song = 8_675_309 }.extend(yaml).to_yaml).must_equal( "--- best_song: 8675309 " @@ -83,7 +85,7 @@ def yaml_representer(&block) let(:yaml_album) do Module.new do include Representable::YAML - property :best_song, :extend => yaml_song, :class => Song + property :best_song, extend: yaml_song, class: Song end end @@ -136,7 +138,7 @@ def yaml_representer(&block) end it "renders a flow style list when :style => :flow set" do - yaml = yaml_representer { collection :songs, :style => :flow } + yaml = yaml_representer { collection :songs, style: :flow } _(album.extend(yaml).to_yaml).must_equal "--- songs: [Jackhammer, Terrible Man] " @@ -169,7 +171,7 @@ def yaml_representer(&block) let(:yaml_album) do Module.new do include Representable::YAML - collection :songs, :class => Song do + collection :songs, class: Song do property :name property :track end