deserializer 0.0.1 → 0.1.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile +3 -8
  4. data/Gemfile.lock +12 -91
  5. data/README.md +30 -7
  6. data/Rakefile +2 -28
  7. data/deserializer.gemspec +2 -0
  8. data/lib/deserializer/base.rb +4 -4
  9. data/lib/deserializer/version.rb +1 -1
  10. data/test/lib/deserializers/deserializers.rb +75 -0
  11. data/test/minitest_helper.rb +14 -0
  12. data/test/unit/deserializer_error_test.rb +12 -0
  13. data/test/unit/deserializer_test.rb +100 -0
  14. metadata +39 -91
  15. data/test/deserializer_test.rb +0 -7
  16. data/test/dummy/README.rdoc +0 -0
  17. data/test/dummy/Rakefile +0 -6
  18. data/test/dummy/app/assets/images/.keep +0 -0
  19. data/test/dummy/app/assets/javascripts/application.js +0 -13
  20. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  21. data/test/dummy/app/controllers/application_controller.rb +0 -5
  22. data/test/dummy/app/controllers/concerns/.keep +0 -0
  23. data/test/dummy/app/helpers/application_helper.rb +0 -2
  24. data/test/dummy/app/mailers/.keep +0 -0
  25. data/test/dummy/app/models/.keep +0 -0
  26. data/test/dummy/app/models/concerns/.keep +0 -0
  27. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  28. data/test/dummy/bin/bundle +0 -3
  29. data/test/dummy/bin/rails +0 -4
  30. data/test/dummy/bin/rake +0 -4
  31. data/test/dummy/bin/setup +0 -29
  32. data/test/dummy/config.ru +0 -4
  33. data/test/dummy/config/application.rb +0 -26
  34. data/test/dummy/config/boot.rb +0 -5
  35. data/test/dummy/config/database.yml +0 -25
  36. data/test/dummy/config/environment.rb +0 -5
  37. data/test/dummy/config/environments/development.rb +0 -41
  38. data/test/dummy/config/environments/production.rb +0 -79
  39. data/test/dummy/config/environments/test.rb +0 -42
  40. data/test/dummy/config/initializers/assets.rb +0 -11
  41. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  42. data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  43. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  44. data/test/dummy/config/initializers/inflections.rb +0 -16
  45. data/test/dummy/config/initializers/mime_types.rb +0 -4
  46. data/test/dummy/config/initializers/session_store.rb +0 -3
  47. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  48. data/test/dummy/config/locales/en.yml +0 -23
  49. data/test/dummy/config/routes.rb +0 -4
  50. data/test/dummy/config/secrets.yml +0 -22
  51. data/test/dummy/lib/assets/.keep +0 -0
  52. data/test/dummy/log/.keep +0 -0
  53. data/test/dummy/public/404.html +0 -67
  54. data/test/dummy/public/422.html +0 -67
  55. data/test/dummy/public/500.html +0 -66
  56. data/test/dummy/public/favicon.ico +0 -0
  57. data/test/integration/navigation_test.rb +0 -10
  58. data/test/test_helper.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0dd737dc7e4c34c7238b6dc22a16077e17c22d3
4
- data.tar.gz: 1d3b4c23174de67667241f4dc91109222bc61d41
3
+ metadata.gz: 16497e6608bbeeb126c16fbb2040022ef43c2a2e
4
+ data.tar.gz: de87e7fd93f070278c1b0e3672edbc4363be0560
5
5
  SHA512:
6
- metadata.gz: d9c5cde9d336f5568761d3d91b39cc697dead376ac6d7f3260da7901aaac333961a71fe7ff1fb0eb7e72446de88b9282e3c850b9c3198aa89fbb92404f2713f0
7
- data.tar.gz: bcedd5145f9015da536d2927bed7fcca82d0b39796e78dc7fd6877da719ce2b9f1e5e31a7d5fd2b60c34b4dd5e46fa4d720829046f4eca2c8691a7fdb07e4fa2
6
+ metadata.gz: b0c1582c067f86f892705e7b7fd73f7ae42dc548354a22170c36b64868febc22a27cba2d306f0130f177062ceb84f548028900d7bb2a086c7be19ec953e7b0ae
7
+ data.tar.gz: 4883819b21807f2915d8887688786aa3f0aecdaa8c411b750e482e6db14ca8e2a68ea041848424a86a9253b6d885902a4db8e881b4ba43beed332b094226543d
data/.gitignore CHANGED
@@ -6,3 +6,4 @@ test/dummy/db/*.sqlite3-journal
6
6
  test/dummy/log/*.log
7
7
  test/dummy/tmp/
8
8
  test/dummy/.sass-cache
9
+ coverage
data/Gemfile CHANGED
@@ -5,11 +5,6 @@ source 'https://rubygems.org'
5
5
  # development dependencies will be added by default to the :development group.
6
6
  gemspec
7
7
 
8
- # Declare any dependencies that are still in development here instead of in
9
- # your gemspec. These might include edge Rails or gems from your path or
10
- # Git. Remember to move these dependencies to your gemspec before releasing
11
- # your gem to rubygems.org.
12
-
13
- # To use a debugger
14
- # gem 'byebug', group: [:development, :test]
15
-
8
+ gem 'rake'
9
+ gem 'simplecov', :group => :test
10
+ gem 'minitest', :group => :test
data/Gemfile.lock CHANGED
@@ -1,106 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- deserializer (0.0.1)
5
- rails (~> 4.2.1)
4
+ deserializer (0.1.0)
6
5
 
7
6
  GEM
8
7
  remote: https://rubygems.org/
9
8
  specs:
10
- actionmailer (4.2.3)
11
- actionpack (= 4.2.3)
12
- actionview (= 4.2.3)
13
- activejob (= 4.2.3)
14
- mail (~> 2.5, >= 2.5.4)
15
- rails-dom-testing (~> 1.0, >= 1.0.5)
16
- actionpack (4.2.3)
17
- actionview (= 4.2.3)
18
- activesupport (= 4.2.3)
19
- rack (~> 1.6)
20
- rack-test (~> 0.6.2)
21
- rails-dom-testing (~> 1.0, >= 1.0.5)
22
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
23
- actionview (4.2.3)
24
- activesupport (= 4.2.3)
25
- builder (~> 3.1)
26
- erubis (~> 2.7.0)
27
- rails-dom-testing (~> 1.0, >= 1.0.5)
28
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
29
- activejob (4.2.3)
30
- activesupport (= 4.2.3)
31
- globalid (>= 0.3.0)
32
- activemodel (4.2.3)
33
- activesupport (= 4.2.3)
34
- builder (~> 3.1)
35
- activerecord (4.2.3)
36
- activemodel (= 4.2.3)
37
- activesupport (= 4.2.3)
38
- arel (~> 6.0)
39
- activesupport (4.2.3)
40
- i18n (~> 0.7)
41
- json (~> 1.7, >= 1.7.7)
42
- minitest (~> 5.1)
43
- thread_safe (~> 0.3, >= 0.3.4)
44
- tzinfo (~> 1.1)
45
- arel (6.0.2)
46
- builder (3.2.2)
47
- erubis (2.7.0)
48
- globalid (0.3.5)
49
- activesupport (>= 4.1.0)
50
- i18n (0.7.0)
51
- json (1.8.3)
52
- loofah (2.0.2)
53
- nokogiri (>= 1.5.9)
54
- mail (2.6.3)
55
- mime-types (>= 1.16, < 3)
56
- mime-types (2.6.1)
57
- mini_portile (0.6.2)
9
+ docile (1.1.5)
58
10
  minitest (5.7.0)
59
- nokogiri (1.6.6.2)
60
- mini_portile (~> 0.6.0)
61
- rack (1.6.4)
62
- rack-test (0.6.3)
63
- rack (>= 1.0)
64
- rails (4.2.3)
65
- actionmailer (= 4.2.3)
66
- actionpack (= 4.2.3)
67
- actionview (= 4.2.3)
68
- activejob (= 4.2.3)
69
- activemodel (= 4.2.3)
70
- activerecord (= 4.2.3)
71
- activesupport (= 4.2.3)
72
- bundler (>= 1.3.0, < 2.0)
73
- railties (= 4.2.3)
74
- sprockets-rails
75
- rails-deprecated_sanitizer (1.0.3)
76
- activesupport (>= 4.2.0.alpha)
77
- rails-dom-testing (1.0.6)
78
- activesupport (>= 4.2.0.beta, < 5.0)
79
- nokogiri (~> 1.6.0)
80
- rails-deprecated_sanitizer (>= 1.0.1)
81
- rails-html-sanitizer (1.0.2)
82
- loofah (~> 2.0)
83
- railties (4.2.3)
84
- actionpack (= 4.2.3)
85
- activesupport (= 4.2.3)
86
- rake (>= 0.8.7)
87
- thor (>= 0.18.1, < 2.0)
11
+ multi_json (1.11.1)
88
12
  rake (10.4.2)
89
- sprockets (3.2.0)
90
- rack (~> 1.0)
91
- sprockets-rails (2.3.2)
92
- actionpack (>= 3.0)
93
- activesupport (>= 3.0)
94
- sprockets (>= 2.8, < 4.0)
95
- sqlite3 (1.3.10)
96
- thor (0.19.1)
97
- thread_safe (0.3.5)
98
- tzinfo (1.2.2)
99
- thread_safe (~> 0.1)
13
+ simplecov (0.9.2)
14
+ docile (~> 1.1.0)
15
+ multi_json (~> 1.0)
16
+ simplecov-html (~> 0.9.0)
17
+ simplecov-html (0.9.0)
100
18
 
101
19
  PLATFORMS
102
20
  ruby
103
21
 
104
22
  DEPENDENCIES
23
+ bundler (~> 1.6)
105
24
  deserializer!
106
- sqlite3
25
+ minitest
26
+ rake
27
+ simplecov
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Deserializer
2
2
 
3
- Deserialization of complex parameters into a hash that an AR model can take.
3
+ Hash transformation and sanitization. Deserialization of complex parameters into a hash that an AR model can take.
4
4
 
5
5
  Lets you have a reverse ActiveModel::Sereializer-like interface that allows for easy create and update without having to write heavy controllers.
6
6
 
@@ -141,7 +141,7 @@ For example with params of `{"title" => "lorem", "text" => "ipsum"}` this desrer
141
141
 
142
142
  #### has_one
143
143
  NOTE: This is the only association currently supported by `Deserializer`.
144
- `has_one` expects the param and its deserializer. So for params `{"ratings" => {"taste" => "bad", "smell" => "good"}}`
144
+ `has_one` expects the param and its deserializer.
145
145
  ```ruby
146
146
  class DishDeserializer < Deserializer::Base
147
147
  # probably other stuff
@@ -153,7 +153,7 @@ class RatingsDeserializer < Deserializer::Base
153
153
  :smell
154
154
  end
155
155
  ```
156
- you would get `{ratings: {taste: "bad", smell: "good"}}`
156
+ So for params `{"ratings" => {"taste" => "bad", "smell" => "good"}}` you would get `{ratings: {taste: "bad", smell: "good"}}`
157
157
 
158
158
  #### Overriding Attribute Methods
159
159
  So let's say in the example above, your internal representation of ratings inside `Dish` is actually called `scores`, you can do
@@ -166,7 +166,7 @@ class DishDeserializer < Deserializer::Base
166
166
  end
167
167
  end
168
168
  ```
169
- which will give you `{scores: {taste: "bad", smell: "good"}}`
169
+ which will give you `{scores: {taste: "bad", smell: "good"}}` for params `{"ratings" => {"taste" => "bad", "smell" => "good"}}`
170
170
 
171
171
  or, if you want to deserialize `ratings` into your `dish` object, you can use `object`
172
172
 
@@ -179,7 +179,7 @@ class DishDeserializer < Deserializer::Base
179
179
  end
180
180
  end
181
181
  ```
182
- which will give you `{taste: "bad", smell: "good"}`
182
+ which will give you `{taste: "bad", smell: "good"}` for params `{"ratings" => {"taste" => "bad", "smell" => "good"}}`
183
183
 
184
184
  or you can deserialize into another subobject by doing
185
185
  ```ruby
@@ -188,7 +188,7 @@ class DishDeserializer < Deserializer::Base
188
188
  has_one :ratings, deserializer: RatingsDeserializer
189
189
 
190
190
  def colors
191
- object[:ratings]
191
+ :ratings
192
192
  end
193
193
  end
194
194
  ```
@@ -263,6 +263,29 @@ class DishReviewsController < YourApiController::Base
263
263
  end
264
264
  end
265
265
 
266
- # rest of RUD
266
+ # RUD
267
267
  end
268
268
  ```
269
+
270
+ ## Installation
271
+
272
+ Add this line to your application's Gemfile:
273
+
274
+ gem 'deserializer'
275
+
276
+ And then execute:
277
+
278
+ $ bundle
279
+
280
+ Or install it yourself as:
281
+
282
+ $ gem install deserializer
283
+
284
+
285
+ ## Contributing
286
+
287
+ 1. Fork it ( https://github.com/[my-github-username]/deserializer/fork )
288
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
289
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
290
+ 4. Push to the branch (`git push origin my-new-feature`)
291
+ 5. Create a new Pull Request
data/Rakefile CHANGED
@@ -1,31 +1,6 @@
1
- begin
2
- require 'bundler/setup'
3
- rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
- end
6
-
7
- require 'rdoc/task'
8
-
9
- RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'Deserializer'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.rdoc')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
15
- end
16
-
17
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
- load 'rails/tasks/engine.rake'
19
-
20
-
21
- load 'rails/tasks/statistics.rake'
22
-
23
-
24
-
25
- Bundler::GemHelper.install_tasks
26
-
27
1
  require 'rake/testtask'
28
2
 
3
+
29
4
  Rake::TestTask.new(:test) do |t|
30
5
  t.libs << 'lib'
31
6
  t.libs << 'test'
@@ -33,5 +8,4 @@ Rake::TestTask.new(:test) do |t|
33
8
  t.verbose = false
34
9
  end
35
10
 
36
-
37
- task default: :test
11
+ task default: :test
data/deserializer.gemspec CHANGED
@@ -18,4 +18,6 @@ Gem::Specification.new do |s|
18
18
  s.test_files = s.files.grep(%r{^(test|s|features)/})
19
19
  s.require_paths = ["lib"]
20
20
 
21
+ s.add_development_dependency "bundler", "~> 1.6"
22
+ s.add_development_dependency "rake"
21
23
  end
@@ -53,7 +53,7 @@ module Deserializer
53
53
  def deserialize
54
54
  self.class.attrs.each do |param_key, object_key|
55
55
  # don't bother with keys that aren't in params
56
- next unless params[param_key]
56
+ next unless params.has_key? param_key
57
57
 
58
58
  # this checks if the object_key is a class that inherits from Deserializer
59
59
  if object_key.is_a?(Class) && object_key < Deserializer::Base
@@ -76,7 +76,7 @@ module Deserializer
76
76
  raise DeserializerError, class: self.class, message: "params cannot be nil"
77
77
  end
78
78
 
79
- self.params = params.deep_symbolize_keys
79
+ self.params = params
80
80
  self.object = object
81
81
  end
82
82
 
@@ -86,10 +86,10 @@ module Deserializer
86
86
  target = self.send( association )
87
87
 
88
88
  unless target.is_a? Hash
89
- target = object[target] = {}
89
+ target = object[target] ||= {}
90
90
  end
91
91
  else
92
- target = object[association] = {}
92
+ target = object[association] ||= {}
93
93
  end
94
94
 
95
95
  deserializer.new( target, params[association] ).deserialize
@@ -1,3 +1,3 @@
1
1
  module Deserializer
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,75 @@
1
+ class BasicDeserializer < Deserializer::Base
2
+ attributes :user_id,
3
+ :text
4
+ end
5
+
6
+ class AttributeDeserializer < Deserializer::Base
7
+ attribute :user_id, key: :user
8
+ attribute :text
9
+ end
10
+
11
+ class VanillaHasOneDeserializer < Deserializer::Base
12
+ attribute :internal, key: :external
13
+
14
+ has_one :params, deserializer: BasicDeserializer
15
+
16
+ end
17
+
18
+ class HasOneWithTargetDeserializer < Deserializer::Base
19
+ attribute :internal, key: :external
20
+
21
+ has_one :thing, deserializer: ::BasicDeserializer
22
+
23
+ def thing
24
+ :user_info
25
+ end
26
+ end
27
+
28
+ class OtherThingDeserializer < Deserializer::Base
29
+ attributes :attr1,
30
+ :attr2
31
+ end
32
+
33
+ class TricksyDeserializer < Deserializer::Base
34
+ attribute :internal, key: :external
35
+
36
+ has_one :thing, deserializer: ::BasicDeserializer
37
+
38
+ has_one :other_thing, deserializer: ::OtherThingDeserializer
39
+
40
+ def thing
41
+ :user_info
42
+ end
43
+
44
+ def other_thing
45
+ :user_info
46
+ end
47
+ end
48
+
49
+ class ExtraTricksyDeserializer < Deserializer::Base
50
+ attribute :internal, key: :external
51
+
52
+ has_one :thing, deserializer: ::BasicDeserializer
53
+
54
+ has_one :other_thing, deserializer: ::OtherThingDeserializer
55
+
56
+ def other_thing
57
+ :thing
58
+ end
59
+ end
60
+
61
+ class HasOneWithObjectTargetDeserializer < Deserializer::Base
62
+ attribute :internal, key: :external
63
+
64
+ has_one :thing, deserializer: ::BasicDeserializer
65
+
66
+ has_one :other_thing, deserializer: ::OtherThingDeserializer
67
+
68
+ def thing
69
+ object
70
+ end
71
+
72
+ def other_thing
73
+ object
74
+ end
75
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
6
+ require 'deserializer'
7
+
8
+ test_libs_path = File.expand_path("../lib", __FILE__)
9
+ Dir[File.join(test_libs_path, "/**/*.rb")].each do |file|
10
+ puts file
11
+ require file
12
+ end
13
+
14
+ require 'minitest/autorun'
@@ -0,0 +1,12 @@
1
+ require 'minitest_helper'
2
+
3
+ class DeserializerErrorTest < Minitest::Test
4
+
5
+ def test_error_contains_message
6
+ begin
7
+ BasicDeserializer.has_one :lolnope
8
+ rescue => e
9
+ assert_equal "BasicDeserializer: has_one associations need a deserilaizer", e.message
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,100 @@
1
+ require 'minitest_helper'
2
+
3
+ class DeserializerTest < Minitest::Test
4
+
5
+ def setup
6
+ @params = { user: 6,
7
+ user_id: 6,
8
+ text: "text",
9
+ i_sholdnt_be_here: :should_i_now}
10
+
11
+ end
12
+
13
+ def test_no_nil_params
14
+ assert_raises Deserializer::DeserializerError do
15
+ BasicDeserializer.from_params nil
16
+ end
17
+ end
18
+
19
+ def test_from_params
20
+ assert_equal ({user_id: 6, text: "text"}) , BasicDeserializer.from_params( @params )
21
+ end
22
+
23
+ def test_permitted_params
24
+ assert_equal [:user_id, :text] , BasicDeserializer.permitted_params
25
+ end
26
+
27
+ def test_does_not_eat_false_or_nil_values
28
+ params = { user_id: nil,
29
+ text: false,
30
+ i_sholdnt_be_here: :should_i_now }
31
+
32
+ assert_equal ({user_id: nil, text: false}) , BasicDeserializer.from_params( params )
33
+ end
34
+
35
+ def test_permitted_params_with_attr_key
36
+ assert_equal [:user, :text] , AttributeDeserializer.permitted_params
37
+ end
38
+
39
+ def test_attribute
40
+ assert_equal "text", AttributeDeserializer.from_params( @params )[:text]
41
+ end
42
+
43
+ def test_attribute_with_key
44
+ assert_equal 6, AttributeDeserializer.from_params( @params )[:user_id]
45
+ end
46
+
47
+ def test_undefined_params_dont_come_through
48
+ assert_equal nil, AttributeDeserializer.from_params( @params )[:i_shouldnt_be_here]
49
+ end
50
+
51
+ def test_has_one
52
+ expected = { internal: :thing, params: { user_id: 6, text: "text" }}
53
+ params = { external: :thing, params: @params }
54
+ assert_equal expected, VanillaHasOneDeserializer.from_params( params )
55
+ end
56
+
57
+ def test_has_one_requires_deserializer
58
+ assert_raises Deserializer::DeserializerError do
59
+ BasicDeserializer.has_one :splosion
60
+ end
61
+ end
62
+
63
+ def test_has_one_with_key_target
64
+ expected = { internal: :thing, user_info: { user_id: 6, text: "text" }}
65
+ params = { external: :thing, thing: @params }
66
+ assert_equal expected, HasOneWithTargetDeserializer.from_params( params )
67
+ end
68
+
69
+ def test_can_combine_two_has_ones_into_a_third_key
70
+ expected = { internal: :thing, user_info: { user_id: 6, text: "text", attr1: :blah, attr2: :blech }}
71
+ params = { external: :thing, thing: @params, other_thing: {attr1: :blah, attr2: :blech} }
72
+ assert_equal expected, TricksyDeserializer.from_params( params )
73
+ end
74
+
75
+
76
+ def test_can_merge_a_has_one_into_another
77
+ expected = { internal: :thing, thing: { user_id: 6, text: "text", attr1: :blah, attr2: :blech }}
78
+ params = { external: :thing, thing: @params, other_thing: {attr1: :blah, attr2: :blech} }
79
+ assert_equal expected, ExtraTricksyDeserializer.from_params( params )
80
+ end
81
+
82
+
83
+ def test_merge_has_one_into_object
84
+ expected = { internal: :thing, user_id: 6, text: "text", attr1: :blah, attr2: :blech }
85
+ params = { external: :thing, thing: @params, other_thing: {attr1: :blah, attr2: :blech} }
86
+ assert_equal expected, HasOneWithObjectTargetDeserializer.from_params( params )
87
+ end
88
+
89
+ def test_has_many_unpermitted
90
+ assert_raises Deserializer::DeserializerError do
91
+ BasicDeserializer.has_many :explodies
92
+ end
93
+ end
94
+
95
+ def test_belongs_to_unpermitted
96
+ assert_raises Deserializer::DeserializerError do
97
+ BasicDeserializer.belongs_to :explody
98
+ end
99
+ end
100
+ end