representable 2.4.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -12
  3. data/CHANGES.md +6 -27
  4. data/README.md +28 -1326
  5. data/lib/representable.rb +4 -14
  6. data/lib/representable/binding.rb +3 -7
  7. data/lib/representable/definition.rb +1 -2
  8. data/lib/representable/populator.rb +35 -0
  9. data/lib/representable/version.rb +1 -1
  10. data/test/definition_test.rb +0 -7
  11. data/test/exec_context_test.rb +2 -2
  12. data/test/instance_test.rb +0 -19
  13. data/test/realistic_benchmark.rb +0 -13
  14. data/test/representable_test.rb +0 -16
  15. data/test/skip_test.rb +1 -1
  16. data/test/test_helper.rb +0 -2
  17. metadata +3 -65
  18. data/lib/representable/deprecations.rb +0 -127
  19. data/lib/representable/parse_strategies.rb +0 -93
  20. data/test-with-deprecations/as_test.rb +0 -65
  21. data/test-with-deprecations/benchmarking.rb +0 -83
  22. data/test-with-deprecations/binding_test.rb +0 -46
  23. data/test-with-deprecations/blaaaaaaaa_test.rb +0 -69
  24. data/test-with-deprecations/cached_test.rb +0 -147
  25. data/test-with-deprecations/class_test.rb +0 -119
  26. data/test-with-deprecations/coercion_test.rb +0 -52
  27. data/test-with-deprecations/config/inherit_test.rb +0 -135
  28. data/test-with-deprecations/config_test.rb +0 -122
  29. data/test-with-deprecations/decorator_scope_test.rb +0 -28
  30. data/test-with-deprecations/decorator_test.rb +0 -96
  31. data/test-with-deprecations/default_test.rb +0 -34
  32. data/test-with-deprecations/defaults_options_test.rb +0 -93
  33. data/test-with-deprecations/definition_test.rb +0 -264
  34. data/test-with-deprecations/example.rb +0 -310
  35. data/test-with-deprecations/examples/object.rb +0 -31
  36. data/test-with-deprecations/exec_context_test.rb +0 -93
  37. data/test-with-deprecations/features_test.rb +0 -70
  38. data/test-with-deprecations/filter_test.rb +0 -57
  39. data/test-with-deprecations/for_collection_test.rb +0 -74
  40. data/test-with-deprecations/generic_test.rb +0 -116
  41. data/test-with-deprecations/getter_setter_test.rb +0 -21
  42. data/test-with-deprecations/hash_bindings_test.rb +0 -87
  43. data/test-with-deprecations/hash_test.rb +0 -160
  44. data/test-with-deprecations/heritage_test.rb +0 -62
  45. data/test-with-deprecations/if_test.rb +0 -79
  46. data/test-with-deprecations/include_exclude_test.rb +0 -88
  47. data/test-with-deprecations/inherit_test.rb +0 -159
  48. data/test-with-deprecations/inline_test.rb +0 -272
  49. data/test-with-deprecations/instance_test.rb +0 -266
  50. data/test-with-deprecations/is_representable_test.rb +0 -77
  51. data/test-with-deprecations/json_test.rb +0 -355
  52. data/test-with-deprecations/lonely_test.rb +0 -239
  53. data/test-with-deprecations/mongoid_test.rb +0 -31
  54. data/test-with-deprecations/nested_test.rb +0 -115
  55. data/test-with-deprecations/object_test.rb +0 -60
  56. data/test-with-deprecations/parse_pipeline_test.rb +0 -64
  57. data/test-with-deprecations/parse_strategy_test.rb +0 -279
  58. data/test-with-deprecations/pass_options_test.rb +0 -27
  59. data/test-with-deprecations/pipeline_test.rb +0 -277
  60. data/test-with-deprecations/populator_test.rb +0 -105
  61. data/test-with-deprecations/prepare_test.rb +0 -67
  62. data/test-with-deprecations/private_options_test.rb +0 -18
  63. data/test-with-deprecations/reader_writer_test.rb +0 -19
  64. data/test-with-deprecations/realistic_benchmark.rb +0 -115
  65. data/test-with-deprecations/render_nil_test.rb +0 -21
  66. data/test-with-deprecations/represent_test.rb +0 -88
  67. data/test-with-deprecations/representable_test.rb +0 -511
  68. data/test-with-deprecations/schema_test.rb +0 -148
  69. data/test-with-deprecations/serialize_deserialize_test.rb +0 -33
  70. data/test-with-deprecations/skip_test.rb +0 -81
  71. data/test-with-deprecations/stringify_hash_test.rb +0 -41
  72. data/test-with-deprecations/test_helper.rb +0 -135
  73. data/test-with-deprecations/test_helper_test.rb +0 -25
  74. data/test-with-deprecations/uncategorized_test.rb +0 -67
  75. data/test-with-deprecations/user_options_test.rb +0 -15
  76. data/test-with-deprecations/wrap_test.rb +0 -152
  77. data/test-with-deprecations/xml_bindings_test.rb +0 -62
  78. data/test-with-deprecations/xml_test.rb +0 -503
  79. data/test-with-deprecations/yaml_test.rb +0 -162
  80. data/test/parse_strategy_test.rb +0 -279
@@ -1,148 +0,0 @@
1
- require 'test_helper'
2
-
3
- # Include Inherit Module And Decorator Test
4
- class SchemaTest < MiniTest::Spec
5
- module Genre
6
- include Representable
7
- property :genre
8
- end
9
-
10
- module LinkFeature
11
- def self.included(base)
12
- base.extend(Link)
13
- end
14
-
15
- module Link
16
- def link
17
- end
18
- end
19
- end
20
-
21
-
22
- module Module
23
- include Representable::Hash
24
- feature LinkFeature
25
-
26
- property :title
27
- property :label do # extend: LabelModule
28
- property :name
29
- link # feature
30
-
31
- property :location do
32
- property :city
33
- link # feature.
34
- end
35
- end
36
-
37
- property :album, :extend => lambda { raise "don't manifest me!" } # this is not an inline decorator, don't manifest it.
38
-
39
-
40
- include Genre # Schema::Included::included is called!
41
- end
42
-
43
-
44
- class WithLocationStreetRepresenter < Representable::Decorator
45
- include Representable::Hash
46
- feature LinkFeature
47
-
48
- property :title
49
- property :label do # extend: LabelModule
50
- property :name
51
- link # feature
52
-
53
- property :location do
54
- property :city
55
- link # feature.
56
- end
57
- end
58
- end
59
-
60
- describe "3-level deep with features" do
61
- let (:label) { OpenStruct.new(:name => "Epitaph", :location => OpenStruct.new(:city => "Sanfran", :name => "DON'T SHOW ME!")) }
62
-
63
- # Module does correctly include features in inlines.
64
- it { band.extend(Module).to_hash.must_equal({"label"=>{"name"=>"Epitaph", "location"=>{"city"=>"Sanfran"}}, "genre"=>"Punkrock"}) }
65
-
66
- # Decorator does correctly include features in inlines.
67
- it { Decorator.new(band).to_hash.must_equal({"label"=>{"name"=>"Epitaph", "location"=>{"city"=>"Sanfran"}}, "genre"=>"Punkrock"}) }
68
- end
69
-
70
-
71
-
72
- class Decorator < Representable::Decorator
73
- feature Representable::Hash
74
-
75
- include Module
76
- end
77
-
78
- # puts Decorator.representable_attrs[:definitions].inspect
79
-
80
- let (:label) { OpenStruct.new(:name => "Fat Wreck", :city => "San Francisco", :employees => [OpenStruct.new(:name => "Mike")], :location => OpenStruct.new(:city => "Sanfran")) }
81
- let (:band) { OpenStruct.new(:genre => "Punkrock", :label => label) }
82
-
83
-
84
- # it { FlatlinersDecorator.new( OpenStruct.new(label: OpenStruct.new) ).
85
- # to_hash.must_equal({}) }
86
- it do
87
- Decorator.new(band).to_hash.must_equal({"genre"=>"Punkrock", "label"=>{"name"=>"Fat Wreck", "location"=>{"city"=>"Sanfran"}}})
88
- end
89
-
90
-
91
- class InheritDecorator < Representable::Decorator
92
- include Representable::Hash
93
-
94
- include Module
95
-
96
- property :label, inherit: true do # decorator.rb:27:in `initialize': superclass must be a Class (Module given)
97
- property :city
98
-
99
- property :location, :inherit => true do
100
- property :city
101
- end
102
- end
103
- end
104
-
105
- it do
106
- InheritDecorator.new(band).to_hash.must_equal({"genre"=>"Punkrock", "label"=>{"name"=>"Fat Wreck", "city"=>"San Francisco", "location"=>{"city"=>"Sanfran"}}})
107
- end
108
-
109
-
110
-
111
- class InheritFromDecorator < InheritDecorator
112
- property :label, inherit: true do
113
- collection :employees do
114
- property :name
115
- end
116
- end
117
- end
118
-
119
- require "pp"
120
- pp InheritFromDecorator.representable_attrs.get(:label)[:extend].(nil).representable_attrs
121
-
122
- it do
123
- InheritFromDecorator.new(band).to_hash.must_equal({"genre"=>"Punkrock", "label"=>{"name"=>"Fat Wreck", "city"=>"San Francisco", "employees"=>[{"name"=>"Mike"}], "location"=>{"city"=>"Sanfran"}}})
124
- end
125
- end
126
-
127
-
128
- class ApplyTest < MiniTest::Spec
129
- class AlbumDecorator < Representable::Decorator
130
- include Representable::Hash
131
-
132
- property :title
133
-
134
- property :hit do
135
- property :title
136
- end
137
-
138
- collection :songs do
139
- property :title
140
- end
141
-
142
- property :band do # yepp, people do crazy stuff like that.
143
- property :label do
144
- property :name
145
- end
146
- end
147
- end
148
- end
@@ -1,33 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SerializeDeserializeTest < BaseTest
4
- subject { Struct.new(:song).new.extend(representer) }
5
-
6
- describe "deserialize" do
7
- representer! do
8
- property :song,
9
- :instance => lambda { |fragment, *| fragment.to_s.upcase },
10
- :prepare => lambda { |fragment, *| fragment },
11
- :deserialize => lambda { |object, fragment, args|
12
- "#{object} #{fragment} #{args.inspect}"
13
- }
14
- end
15
-
16
- it { subject.from_hash({"song" => Object}, {:volume => 9}).song.must_equal "OBJECT Object {:volume=>9}" }
17
- end
18
-
19
- describe "serialize" do
20
- representer! do
21
- property :song,
22
- :representable => true,
23
- :prepare => lambda { |fragment, *| fragment },
24
- :serialize => lambda { |object, args|
25
- "#{object} #{args.inspect}"
26
- }
27
- end
28
-
29
- before { subject.song = "Arrested In Shanghai" }
30
-
31
- it { subject.to_hash({:volume => 9}).must_equal({"song"=>"Arrested In Shanghai {:volume=>9}"}) }
32
- end
33
- end
@@ -1,81 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SkipParseTest < MiniTest::Spec
4
- representer! do
5
- property :title, skip_parse: lambda { |fragment, opts| opts[:skip?] and fragment == "skip me" }
6
- property :band,
7
- skip_parse: lambda { |fragment, opts| opts[:skip?] and fragment["name"].nil? }, class: OpenStruct do
8
- property :name
9
- end
10
-
11
- collection :airplays,
12
- skip_parse: lambda { |fragment, opts| opts[:skip?] and fragment["station"].nil? }, class: OpenStruct do
13
- property :station
14
- end
15
- end
16
-
17
- let (:song) { OpenStruct.new.extend(representer) }
18
-
19
- # do parse.
20
- it do
21
- song.from_hash({
22
- "title" => "Victim Of Fate",
23
- "band" => {"name" => "Mute 98"},
24
- "airplays" => [{"station" => "JJJ"}]
25
- }, skip?: true)
26
-
27
- song.title.must_equal "Victim Of Fate"
28
- song.band.name.must_equal "Mute 98"
29
- song.airplays[0].station.must_equal "JJJ"
30
- end
31
-
32
- # skip parsing.
33
- let (:airplay) { OpenStruct.new(station: "JJJ") }
34
-
35
- it do
36
- song.from_hash({
37
- "title" => "skip me",
38
- "band" => {},
39
- "airplays" => [{"station" => "JJJ"}, {}],
40
- }, skip?: true)
41
-
42
- song.title.must_equal nil
43
- song.band.must_equal nil
44
- song.airplays.must_equal [airplay]
45
- end
46
- end
47
-
48
- class SkipRenderTest < MiniTest::Spec
49
- representer! do
50
- property :title
51
- property :band,
52
- skip_render: lambda { |object, opts| opts[:skip?] and object.name == "Rancid" } do
53
- property :name
54
- end
55
-
56
- collection :airplays,
57
- skip_render: lambda { |object, opts| puts object.inspect; opts[:skip?] and object.station == "Radio Dreyeckland" } do
58
- property :station
59
- end
60
- end
61
-
62
- let (:song) { OpenStruct.new(title: "Black Night", band: OpenStruct.new(name: "Time Again")).extend(representer) }
63
- let (:skip_song) { OpenStruct.new(title: "Time Bomb", band: OpenStruct.new(name: "Rancid")).extend(representer) }
64
-
65
- # do render.
66
- it { song.to_hash(skip?: true).must_equal({"title"=>"Black Night", "band"=>{"name"=>"Time Again"}}) }
67
- # skip.
68
- it { skip_song.to_hash(skip?: true).must_equal({"title"=>"Time Bomb"}) }
69
-
70
- # do render all collection items.
71
- it do
72
- song = OpenStruct.new(airplays: [OpenStruct.new(station: "JJJ"), OpenStruct.new(station: "ABC")]).extend(representer)
73
- song.to_hash(skip?: true).must_equal({"airplays"=>[{"station"=>"JJJ"}, {"station"=>"ABC"}]})
74
- end
75
-
76
- # skip middle item.
77
- it do
78
- song = OpenStruct.new(airplays: [OpenStruct.new(station: "JJJ"), OpenStruct.new(station: "Radio Dreyeckland"), OpenStruct.new(station: "ABC")]).extend(representer)
79
- song.to_hash(skip?: true).must_equal({"airplays"=>[{"station"=>"JJJ"}, {"station"=>"ABC"}]})
80
- end
81
- end
@@ -1,41 +0,0 @@
1
- require 'test_helper'
2
-
3
- class StringifyHashTest < MiniTest::Spec
4
- describe "#from_hash" do
5
- representer!(:name => :song_representer) do
6
-
7
- include Representable::Hash
8
- include Representable::Hash::AllowSymbols
9
-
10
- property :title
11
- end
12
-
13
- representer!(:inject => :song_representer) do
14
- include Representable::Hash::AllowSymbols
15
-
16
- property :song, :extend => song_representer, :class => OpenStruct
17
- end
18
-
19
- it "parses symbols, too" do
20
- OpenStruct.new.extend(representer).from_hash({:song => {:title => "Der Optimist"}}).song.title.must_equal "Der Optimist"
21
- end
22
-
23
- it "still parses strings" do
24
- OpenStruct.new.extend(representer).from_hash({"song" => {"title" => "Der Optimist"}}).song.title.must_equal "Der Optimist"
25
- end
26
-
27
- describe "with :wrap" do
28
- representer!(:inject => :song_representer) do
29
- include Representable::Hash::AllowSymbols
30
-
31
- self.representation_wrap = :album
32
- property :song, :extend => song_representer, :class => OpenStruct
33
- end
34
-
35
- it "parses symbols, too" do
36
- OpenStruct.new.extend(representer).from_hash({:album => {:song => {:title => "Der Optimist"}}}).song.title.must_equal "Der Optimist"
37
- end
38
- end
39
- end
40
-
41
- end
@@ -1,135 +0,0 @@
1
- require 'representable'
2
-
3
- require "json"
4
- require "psych"
5
-
6
- require 'representable/json'
7
- require 'representable/xml'
8
- require 'representable/yaml'
9
- require 'minitest/autorun'
10
- require 'test_xml/mini_test'
11
-
12
- require "representable/debug"
13
-
14
- class Album
15
- attr_accessor :songs, :best_song
16
- def initialize(songs=nil, best_song=nil)
17
- @songs = songs
18
- @best_song = best_song
19
- end
20
-
21
- def ==(other)
22
- songs == other.songs and best_song == other.best_song
23
- end
24
- end
25
-
26
- class Song
27
- attr_accessor :name, :track # never change this, track rendered with Rails#to_json.
28
- def initialize(name=nil, track=nil)
29
- @name = name
30
- @track = track
31
- end
32
-
33
- def ==(other)
34
- name == other.name and track == other.track
35
- end
36
- end
37
-
38
- module XmlHelper
39
- def xml(document)
40
- Nokogiri::XML(document).root
41
- end
42
- end
43
-
44
- module AssertJson
45
- module Assertions
46
- def assert_json(expected, actual, msg=nil)
47
- msg = message(msg, "") { diff expected, actual }
48
- assert(expected.split("").sort == actual.split("").sort, msg)
49
- end
50
- end
51
- end
52
-
53
- MiniTest::Spec.class_eval do
54
- include AssertJson::Assertions
55
- include XmlHelper
56
-
57
- def self.for_formats(formats)
58
- formats.each do |format, cfg|
59
- mod, output, input = cfg
60
- yield format, mod, output, input
61
- end
62
- end
63
-
64
- def render(object, *args)
65
- AssertableDocument.new(object.send("to_#{format}", *args), format)
66
- end
67
-
68
- def parse(object, input, *args)
69
- object.send("from_#{format}", input, *args)
70
- end
71
-
72
- class AssertableDocument
73
- attr_reader :document
74
-
75
- def initialize(document, format)
76
- @document, @format = document, format
77
- end
78
-
79
- def must_equal_document(*args)
80
- return document.must_equal_xml(*args) if @format == :xml
81
- document.must_equal(*args)
82
- end
83
- end
84
-
85
- def self.representer!(options={}, &block)
86
- fmt = options # we need that so the 2nd call to ::let (within a ::describe) remembers the right format.
87
-
88
- name = options[:name] || :representer
89
- format = options[:module] || Representable::Hash
90
-
91
- let(name) do
92
- mod = options[:decorator] ? Class.new(Representable::Decorator) : Module.new
93
-
94
- inject_representer(mod, fmt)
95
-
96
- mod.module_eval do
97
- include format
98
- instance_exec(&block)
99
- end
100
-
101
- mod
102
- end
103
-
104
- def inject_representer(mod, options)
105
- return unless options[:inject]
106
-
107
- injected_name = options[:inject]
108
- injected = send(injected_name) # song_representer
109
- mod.singleton_class.instance_eval do
110
- define_method(injected_name) { injected }
111
- end
112
- end
113
- end
114
-
115
- module TestMethods
116
- def representer_for(modules=[Representable::Hash], &block)
117
- Module.new do
118
- extend TestMethods
119
- include *modules
120
- module_exec(&block)
121
- end
122
- end
123
-
124
- alias_method :representer!, :representer_for
125
- end
126
- include TestMethods
127
- end
128
-
129
- class BaseTest < MiniTest::Spec
130
- let (:new_album) { OpenStruct.new.extend(representer) }
131
- let (:album) { OpenStruct.new(:songs => ["Fuck Armageddon"]).extend(representer) }
132
- let (:song) { OpenStruct.new(:title => "Resist Stance") }
133
- let (:song_representer) { Module.new do include Representable::Hash; property :title end }
134
-
135
- end
@@ -1,25 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestHelperTest < MiniTest::Spec
4
- describe "#assert_json" do
5
- it "tests for equality" do
6
- assert_json "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}", "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}"
7
- end
8
-
9
- it "allows different key orders" do
10
- assert_json "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}", "{\"songs\":{\"two\":\"Emo Boy\",\"one\":\"65\"}}"
11
- end
12
-
13
- it "complains when expected hash is subset" do
14
- assert_raises MiniTest::Assertion do
15
- assert_json "{\"songs\":{\"one\":\"65\"}}", "{\"songs\":{\"two\":\"Emo Boy\",\"one\":\"65\"}}"
16
- end
17
- end
18
-
19
- it "complains when source hash is subset" do
20
- assert_raises MiniTest::Assertion do
21
- assert_json "{\"songs\":{\"two\":\"Emo Boy\",\"one\":\"65\"}}", "{\"songs\":{\"one\":\"65\"}}"
22
- end
23
- end
24
- end
25
- end