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,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