representable 2.4.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,96 +0,0 @@
1
- require 'test_helper'
2
-
3
- class DecoratorTest < MiniTest::Spec
4
- class SongRepresentation < Representable::Decorator
5
- include Representable::JSON
6
- property :name
7
- end
8
-
9
- class AlbumRepresentation < Representable::Decorator
10
- include Representable::JSON
11
-
12
- collection :songs, :class => Song, :extend => SongRepresentation
13
- end
14
-
15
- let (:song) { Song.new("Mama, I'm Coming Home") }
16
- let (:album) { Album.new([song]) }
17
-
18
- describe "inheritance" do
19
- let (:inherited_decorator) do
20
- Class.new(AlbumRepresentation) do
21
- property :best_song
22
- end.new(Album.new([song], "Stand Up"))
23
- end
24
-
25
- it { inherited_decorator.to_hash.must_equal({"songs"=>[{"name"=>"Mama, I'm Coming Home"}], "best_song"=>"Stand Up"}) }
26
- end
27
-
28
- let (:decorator) { AlbumRepresentation.new(album) }
29
-
30
- it "renders" do
31
- decorator.to_hash.must_equal({"songs"=>[{"name"=>"Mama, I'm Coming Home"}]})
32
- album.wont_respond_to :to_hash
33
- song.wont_respond_to :to_hash # DISCUSS: weak test, how to assert blank slate?
34
- # no @representable_attrs in decorated objects
35
- song.instance_variable_get(:@representable_attrs).must_equal nil
36
- end
37
-
38
- describe "#from_hash" do
39
- it "returns represented" do
40
- decorator.from_hash({"songs"=>[{"name"=>"Mama, I'm Coming Home"}]}).must_equal album
41
- end
42
-
43
- it "parses" do
44
- decorator.from_hash({"songs"=>[{"name"=>"Atomic Garden"}]})
45
- album.songs.first.must_be_kind_of Song
46
- album.songs.must_equal [Song.new("Atomic Garden")]
47
- album.wont_respond_to :to_hash
48
- song.wont_respond_to :to_hash # DISCUSS: weak test, how to assert blank slate?
49
- end
50
- end
51
-
52
- describe "#decorated" do
53
- it "is aliased to #represented" do
54
- AlbumRepresentation.prepare(album).decorated.must_equal album
55
- end
56
- end
57
-
58
-
59
- describe "inline decorators" do
60
- representer!(decorator: true) do
61
- collection :songs, :class => Song do
62
- property :name
63
- end
64
- end
65
-
66
- it "does not pollute represented" do
67
- representer.new(album).from_hash({"songs"=>[{"name"=>"Atomic Garden"}]})
68
-
69
- # no @representable_attrs in decorated objects
70
- song.instance_variable_get(:@representable_attrs).must_equal nil
71
- album.instance_variable_get(:@representable_attrs).must_equal nil
72
- end
73
- end
74
- end
75
-
76
- require "uber/inheritable_attr"
77
- class InheritanceWithDecoratorTest < MiniTest::Spec
78
- class Twin
79
- extend Uber::InheritableAttr
80
- inheritable_attr :representer_class
81
- self.representer_class = Class.new(Representable::Decorator){ include Representable::Hash }
82
- end
83
-
84
- class Album < Twin
85
- representer_class.property :title # Twin.representer_class.clone
86
- end
87
-
88
- class Song < Twin # Twin.representer_class.clone
89
- end
90
-
91
- it do
92
- Twin.representer_class.definitions.size.must_equal 0
93
- Album.representer_class.definitions.size.must_equal 1
94
- Song.representer_class.definitions.size.must_equal 0
95
- end
96
- end
@@ -1,34 +0,0 @@
1
- require "test_helper"
2
-
3
- class DefaultTest < MiniTest::Spec
4
- Song = Struct.new(:id, :title)
5
-
6
- representer! do
7
- property :id
8
- property :title, default: "Huber Breeze" #->(options) { options[:default] }
9
- end
10
-
11
- describe "#from_hash" do
12
- let (:song) { Song.new.extend(representer) }
13
-
14
- it { song.from_hash({}).must_equal Song.new(nil, "Huber Breeze") }
15
- # default doesn't apply when empty string.
16
- it { song.from_hash({"title"=>""}).must_equal Song.new(nil, "") }
17
- it { song.from_hash({"title"=>nil}).must_equal Song.new(nil, nil) }
18
- it { song.from_hash({"title"=>"Blindfold"}).must_equal Song.new(nil, "Blindfold") }
19
- end
20
-
21
- describe "#to_json" do
22
- it "uses :default when not available from object" do
23
- Song.new.extend(representer).to_hash.must_equal({"title"=>"Huber Breeze"})
24
- end
25
-
26
- it "uses value from represented object when present" do
27
- Song.new(nil, "After The War").extend(representer).to_hash.must_equal({"title"=>"After The War"})
28
- end
29
-
30
- it "uses value from represented object when emtpy string" do
31
- Song.new(nil, "").extend(representer).to_hash.must_equal({"title"=>""})
32
- end
33
- end
34
- end
@@ -1,93 +0,0 @@
1
- require 'test_helper'
2
-
3
- class DefaultsOptionsTest < BaseTest
4
- let (:format) { :hash }
5
- let (:song) { Struct.new(:title, :author_name, :song_volume, :description).new("Revolution", "Some author", 20, nil) }
6
- let (:prepared) { representer.prepare song }
7
-
8
- describe "hash options combined with dynamic options" do
9
- representer! do
10
- defaults render_nil: true do |name|
11
- { as: name.to_s.upcase }
12
- end
13
-
14
- property :title
15
- property :author_name
16
- property :description
17
- property :song_volume
18
- end
19
-
20
- it { render(prepared).must_equal_document({"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "DESCRIPTION" => nil, "SONG_VOLUME" => 20}) }
21
- end
22
-
23
- describe "with only dynamic property options" do
24
- representer! do
25
- defaults do |name|
26
- { as: name.to_s.upcase }
27
- end
28
-
29
- property :title
30
- property :author_name
31
- property :description
32
- property :song_volume
33
- end
34
-
35
- it { render(prepared).must_equal_document({"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "SONG_VOLUME" => 20}) }
36
- end
37
-
38
- describe "with only hashes" do
39
- representer! do
40
- defaults render_nil: true
41
-
42
- property :title
43
- property :author_name
44
- property :description
45
- property :song_volume
46
- end
47
-
48
- it { render(prepared).must_equal_document({"title" => "Revolution", "author_name" => "Some author", "description" => nil, "song_volume" => 20}) }
49
- end
50
-
51
- describe "direct defaults hash" do
52
- representer! do
53
- defaults render_nil: true
54
-
55
- property :title
56
- property :author_name
57
- property :description
58
- property :song_volume
59
- end
60
-
61
- it { render(prepared).must_equal_document({"title" => "Revolution", "author_name" => "Some author", "description" => nil, "song_volume" => 20}) }
62
- end
63
-
64
- describe "direct defaults hash with dynamic options" do
65
- representer! do
66
- defaults render_nil: true do |name|
67
- { as: name.to_s.upcase }
68
- end
69
-
70
- property :title
71
- property :author_name
72
- property :description
73
- property :song_volume
74
- end
75
-
76
- it { render(prepared).must_equal_document({"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "DESCRIPTION" => nil, "SONG_VOLUME" => 20}) }
77
- end
78
-
79
- describe "prioritizes specific options" do
80
- representer! do
81
- defaults render_nil: true do |name|
82
- { as: name.to_s.upcase }
83
- end
84
-
85
- property :title
86
- property :author_name
87
- property :description, render_nil: false
88
- property :song_volume, as: :volume
89
- end
90
-
91
- it { render(prepared).must_equal_document({"TITLE" => "Revolution", "AUTHOR_NAME" => "Some author", "volume" => 20}) }
92
- end
93
- end
@@ -1,264 +0,0 @@
1
- require 'test_helper'
2
-
3
- class DefinitionTest < MiniTest::Spec
4
- Definition = Representable::Definition
5
-
6
- # TODO: test that we DON'T clone options, that must happen in
7
- describe "#initialize" do
8
- it do
9
- opts = nil
10
-
11
- # new yields the defaultized options HASH.
12
- definition = Definition.new(:song, :extend => Module) do |options|
13
- options[:awesome] = true
14
- options[:parse_filter] << 1
15
-
16
- # default variables
17
- options[:as].must_equal nil
18
- options[:extend].must_equal Module
19
- end
20
- definition.name.must_equal "song"
21
-
22
- #
23
- definition[:awesome].must_equal true
24
- definition[:parse_filter].must_equal Representable::Pipeline[1]
25
- definition[:render_filter].must_equal Representable::Pipeline[]
26
- end
27
- end
28
-
29
- describe "#[]" do
30
- let (:definition) { Definition.new(:song) }
31
- # default is nil.
32
- it { definition[:bla].must_equal nil }
33
- end
34
-
35
- # merge!
36
- describe "#merge!" do
37
- let (:definition) { Definition.new(:song, :whatever => true) }
38
-
39
- # merges new options.
40
- it { definition.merge!(:something => true)[:something].must_equal true }
41
- # doesn't override original options.
42
- it { definition.merge!({:something => true})[:whatever].must_equal true }
43
- # override original when passed in #merge!.
44
- it { definition.merge!({:whatever => false})[:whatever].must_equal false }
45
-
46
-
47
- it "runs macros" do
48
- definition[:setter].must_equal nil
49
- definition.merge!(:parse_strategy => :sync)
50
- definition[:setter].must_respond_to :evaluate
51
- end
52
-
53
- # with block
54
- it do
55
- definition = Definition.new(:song, :extend => Module).merge!({:something => true}) do |options|
56
- options[:awesome] = true
57
- options[:render_filter] << 1
58
-
59
- # default variables
60
- # options[:as].must_equal "song"
61
- # options[:extend].must_equal Module
62
- end
63
-
64
- definition[:awesome].must_equal true
65
- definition[:something].must_equal true
66
- definition[:render_filter].must_equal Representable::Pipeline[1]
67
- definition[:parse_filter].must_equal Representable::Pipeline[]
68
- end
69
-
70
- describe "with :parse_filter" do
71
- let (:definition) { Definition.new(:title, :parse_filter => 1) }
72
-
73
- # merges :parse_filter and :render_filter.
74
- it do
75
- merged = definition.merge!(:parse_filter => 2)[:parse_filter]
76
-
77
- merged.must_be_kind_of Representable::Pipeline
78
- merged.size.must_equal 2
79
- end
80
-
81
- # :parse_filter can also be array.
82
- it { definition.merge!(:parse_filter => [2, 3])[:parse_filter].size.must_equal 3 }
83
- end
84
-
85
- # does not change arguments
86
- it do
87
- Definition.new(:title).merge!(options = {:whatever => 1})
88
- options.must_equal(:whatever => 1)
89
- end
90
- end
91
-
92
-
93
- # delete!
94
- describe "#delete!" do
95
- let (:definition) { Definition.new(:song, serialize: "remove me!") }
96
-
97
- before { definition[:serialize].evaluate(nil).must_equal "remove me!" }
98
-
99
- it { definition.delete!(:serialize)[:serialize].must_equal nil }
100
- end
101
-
102
- # #inspect
103
- describe "#inspect" do
104
- it { Definition.new(:songs).inspect.must_equal "#<Representable::Definition ==>songs @options={:name=>\"songs\", :parse_filter=>[], :render_filter=>[]}>" }
105
- end
106
-
107
-
108
- describe "generic API" do
109
- before do
110
- @def = Representable::Definition.new(:songs)
111
- end
112
-
113
- it "responds to #representer_module" do
114
- assert_equal nil, Representable::Definition.new(:song).representer_module
115
- assert_equal Hash, Representable::Definition.new(:song, :extend => Hash).representer_module
116
- end
117
-
118
- describe "#typed?" do
119
- it "is false per default" do
120
- assert ! @def.typed?
121
- end
122
-
123
- it "is true when :class is present" do
124
- assert Representable::Definition.new(:songs, :class => Hash).typed?
125
- end
126
-
127
- it "is true when :extend is present, only" do
128
- assert Representable::Definition.new(:songs, :extend => Hash).typed?
129
- end
130
-
131
- it "is true when :instance is present, only" do
132
- assert Representable::Definition.new(:songs, :instance => Object.new).typed?
133
- end
134
- end
135
-
136
-
137
- describe "#representable?" do
138
- it { assert Definition.new(:song, :representable => true).representable? }
139
- it { Definition.new(:song, :representable => true, :extend => Object).representable?.must_equal true }
140
- it { refute Definition.new(:song, :representable => false, :extend => Object).representable? }
141
- it { assert Definition.new(:song, :extend => Object).representable? }
142
- it { refute Definition.new(:song).representable? }
143
- end
144
-
145
-
146
- it "responds to #getter and returns string" do
147
- assert_equal "songs", @def.getter
148
- end
149
-
150
- it "responds to #name" do
151
- assert_equal "songs", @def.name
152
- end
153
-
154
- it "responds to #setter" do
155
- assert_equal :"songs=", @def.setter
156
- end
157
-
158
- describe "nested: FIXME" do
159
- it do
160
- dfn = Representable::Definition.new(:songs, nested: Module)
161
- assert dfn.typed?
162
- dfn[:extend].(nil).must_equal Module
163
- end
164
- end
165
-
166
-
167
- describe "#clone" do
168
- subject { Representable::Definition.new(:title, :volume => 9, :clonable => Uber::Options::Value.new(1)) }
169
-
170
- it { subject.clone.must_be_kind_of Representable::Definition }
171
- it { subject.clone[:clonable].evaluate(nil).must_equal 1 }
172
-
173
- it "clones @options" do
174
- @def.merge!(:volume => 9)
175
-
176
- cloned = @def.clone
177
- cloned.merge!(:volume => 8)
178
-
179
- assert_equal @def[:volume], 9
180
- assert_equal cloned[:volume], 8
181
- end
182
- end
183
- end
184
-
185
- describe "#has_default?" do
186
- it "returns false if no :default set" do
187
- assert_equal false, Representable::Definition.new(:song).has_default?
188
- end
189
-
190
- it "returns true if :default set" do
191
- assert_equal true, Representable::Definition.new(:song, :default => nil).has_default?
192
- end
193
- end
194
-
195
-
196
- describe "#binding" do
197
- it "returns true when :binding is set" do
198
- assert Representable::Definition.new(:songs, :binding => Object)[:binding]
199
- end
200
-
201
- it "returns false when :binding is not set" do
202
- assert !Representable::Definition.new(:songs)[:binding]
203
- end
204
- end
205
-
206
- describe "#create_binding" do
207
- it "executes the block (without special context)" do
208
- definition = Representable::Definition.new(:title, :binding => lambda { |*args| @binding = Representable::Binding.new(*args) })
209
- definition.create_binding.must_equal @binding
210
- end
211
- end
212
-
213
- describe ":collection => true" do
214
- before do
215
- @def = Representable::Definition.new(:songs, :collection => true, :tag => :song)
216
- end
217
-
218
- it "responds to #array?" do
219
- assert @def.array?
220
- end
221
- end
222
-
223
-
224
- describe ":default => value" do
225
- it "responds to #default" do
226
- @def = Representable::Definition.new(:song)
227
- assert_equal nil, @def[:default]
228
- end
229
-
230
- it "accepts a default value" do
231
- @def = Representable::Definition.new(:song, :default => "Atheist Peace")
232
- assert_equal "Atheist Peace", @def[:default]
233
- end
234
- end
235
-
236
- describe ":hash => true" do
237
- before do
238
- @def = Representable::Definition.new(:songs, :hash => true)
239
- end
240
-
241
- it "responds to #hash?" do
242
- assert @def.hash?
243
- assert ! Representable::Definition.new(:songs).hash?
244
- end
245
- end
246
-
247
- describe ":binding => Object" do
248
- subject do
249
- Representable::Definition.new(:songs, :binding => Object)
250
- end
251
-
252
- it "responds to #binding" do
253
- assert_equal subject[:binding], Object
254
- end
255
- end
256
-
257
- describe "#[]=" do
258
- it "raises exception since it's deprecated" do
259
- assert_raises NoMethodError do
260
- Definition.new(:title)[:extend] = Module.new # use merge! after initialize.
261
- end
262
- end
263
- end
264
- end