media_types-serialization 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8bff701e51e128e250514cb3b951409907496d54ac1c9bbfdcea02c269d0c09
4
- data.tar.gz: 519cf91eb85882e2f37b4a7f500025f96ce6551bda4798e2c4d9f8ca7d9813b4
3
+ metadata.gz: 0c7c8556cbaffc26158c2b8b0cadef6e1544f532a47e03d6580b9518416240f2
4
+ data.tar.gz: 49a6897feba02f920cce9d32ee6b4ea4f5838446404ce2bdf1d08b52ba4f1ef5
5
5
  SHA512:
6
- metadata.gz: f69cb4908449138b1c0f6aa080df5ed9401d2ee344356199843ca92543c2c5b2539dbb2b7e4a342a8d583d7a6ac054f2e45c345a4a663178473cdc2a2bd25d1e
7
- data.tar.gz: 95345bbf3f598c613926b2531496ee89a99c6bc16199bb025e033d9d065b4d34ab97efc63d03f43a12cf63e55ce8acb760f4ace0d8587e889ce2f5375d5ef060
6
+ metadata.gz: 2400a94296b4f57e386b1a7b115511873ed449b58a8148b0bc64114942a5720db2270af8f1d7878e284aa6b2c58f713b0f7dd6ba297278132f7f496e18aaa2b7
7
+ data.tar.gz: d93e89709b0d19111b6d3e0cfc1608fc386611ae80132df228af8c27ed43b30f4a739963b5d492e24184e83db4f86baac001834b30a0297e53577ce662f42c7c
data/.gitignore CHANGED
@@ -1,12 +1,12 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- .idea/workspace.xml
11
- .idea/usage.statistics.xml
12
- .idea/tasks.xml
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ .idea/workspace.xml
11
+ .idea/usage.statistics.xml
12
+ .idea/tasks.xml
data/.idea/.rakeTasks CHANGED
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <Settings><!--This file was automatically generated by Ruby plugin.
3
- You are allowed to:
4
- 1. Remove rake task
5
- 2. Add existing rake tasks
6
- To add existing rake tasks automatically delete this file and reload the project.
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
7
  --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build media_types-serialization-0.3.1.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove any temporary products" fullCmd="clean" taksId="clean" /><RakeTask description="Remove any generated files" fullCmd="clobber" taksId="clobber" /><RakeTask description="Build and install media_types-serialization-0.3.1.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install media_types-serialization-0.3.1.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.3.1 and build and push media_types-serialization-0.3.1.gem to rubygems.org" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="Run tests" fullCmd="test" taksId="test" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
@@ -1,6 +1,6 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
5
- </profile>
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
5
+ </profile>
6
6
  </component>
@@ -1,20 +1,20 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration default="false" name="test" type="RakeRunConfigurationType" factoryName="Rake">
3
- <module name="media_types-serialization" />
4
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" />
5
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
6
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
7
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
8
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
9
- <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="true" />
10
- <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
11
- <EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov" />
12
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="test" />
13
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" />
14
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":test_unit " />
15
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" />
16
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" />
17
- <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" />
18
- <method v="2" />
19
- </configuration>
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="false" name="test" type="RakeRunConfigurationType" factoryName="Rake">
3
+ <module name="media_types-serialization" />
4
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" />
5
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
6
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
7
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
8
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
9
+ <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="true" />
10
+ <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
11
+ <EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov" />
12
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="test" />
13
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" />
14
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":test_unit " />
15
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" />
16
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" />
17
+ <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" />
18
+ <method v="2" />
19
+ </configuration>
20
20
  </component>
data/.travis.yml CHANGED
@@ -1,17 +1,17 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.5
7
- - 2.6
8
- - ruby-head
9
- before_install:
10
- - gem install bundler -v 2.0.1
11
- - gem update --system
12
- - gem --version
13
- matrix:
14
- allow_failures:
15
- - rvm: ruby-head
16
- install:
17
- - bundle install --with development --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5
7
+ - 2.6
8
+ - ruby-head
9
+ before_install:
10
+ - gem install bundler -v 2.0.1
11
+ - gem update --system
12
+ - gem --version
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: ruby-head
16
+ install:
17
+ - bundle install --with development --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0
4
+
5
+ - Change wrappers to extend from `SimpleDelegator`
6
+ - Move `RootKey` to `Base.root_key` method so it can be overridden
7
+ - Move `MediaWrapper.wrap` to `Base.wrap` method so it can be overridden
8
+ - Move `MediaObjectWrapper::AUTO_UNWRAP_KLAZZES` to `MediaObjectWrapper.auto_unwrap_klazzes` option
9
+ - Add `::MediaTypes::Serialization.html_wrapper_layout` option
10
+ - Add `MediaObjectWrapper#unwrapped_serializable` which can be overridden in `Base#unwrapped_serializable`
11
+ - Add `MediaIndexWrapper#wrapped_serializable` which can be overridden in `Base#wrapped_serializable`
12
+ - Add `MediaCollectionWrapper#wrapped_serializable` which can be overridden in `Base#wrapped_serializable`
13
+ - Fix empty link handler (`{ rel: nil }`)
14
+ - Fix `NoSerializerForContentType` error message
15
+ - Add tests for `root_key`, `wrap`, `MediaObjectWrapper`, `MediaIndexWrapper` and `MediaCollectionWrapper`
16
+
3
17
  ## 0.4.0
4
18
 
5
19
  - Change `extract_links` to `extract_links(view:)` and mimic `header_links(view:)`
data/CODE_OF_CONDUCT.md CHANGED
@@ -1,74 +1,74 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at derk-jan+github@karrenbeld.info. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at derk-jan+github@karrenbeld.info. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in media_types-serialization.gemspec
4
- gemspec
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in media_types-serialization.gemspec
4
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- media_types-serialization (0.4.0)
4
+ media_types-serialization (0.5.0)
5
5
  actionpack (>= 4.0.0)
6
6
  activesupport (>= 4.0.0)
7
7
  http_headers-accept (< 1.0.0)
@@ -39,7 +39,7 @@ GEM
39
39
  http_headers-link (0.2.1)
40
40
  http_headers-utils (>= 0.2.0, < 1.0.0)
41
41
  http_headers-utils (0.2.0)
42
- i18n (1.5.3)
42
+ i18n (1.6.0)
43
43
  concurrent-ruby (~> 1.0)
44
44
  loofah (2.2.3)
45
45
  crass (~> 1.0.2)
data/LICENSE.txt CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2019 Derk-Jan Karrenbeld
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Derk-Jan Karrenbeld
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -218,6 +218,25 @@ end
218
218
  If you want the link header to be different from the `_links`, you can implement `header_links(view:)` next to
219
219
  `extract_links(view:)`. This will be called by the `to_link_header` function.
220
220
 
221
+ ### Validation
222
+ If you only have `json`/`xml`/structured data responses and you want to use [`media_types-validation`](https://github.com/XPBytes/media_types-validation) in conjunction with this gem, you can create a concern or add the following two functions to your base controller:
223
+
224
+ ```ruby
225
+ def render_media(resource = @resource, **opts)
226
+ serializer = serialize_media(resource)
227
+ render media: serializer, content_type: request.format.to_s, **opts
228
+ validate_media(serializer)
229
+ end
230
+
231
+ def validate_media(serializer = @last_media_serializer)
232
+ media_type = serializer.current_media_type
233
+ return true unless media_type && response_body
234
+ validate_json_with_media_type(serializer.to_hash, media_type: media_type)
235
+ end
236
+ ```
237
+
238
+ As long as the serializer has a `to_json` or `to_hash`, this will work -- but also means that the data will always be validate _as if_ it were json. This covers most use cases.
239
+
221
240
  ### Related
222
241
 
223
242
  - [`MediaTypes`](https://github.com/SleeplessByte/media-types-ruby): :gem: Library to create media type definitions, schemes and validations
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
8
- end
9
-
10
- task :default => :test
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console CHANGED
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "media_types/serialization"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "media_types/serialization"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -10,13 +10,13 @@ require 'http_headers/accept'
10
10
 
11
11
  require 'media_types/serialization/no_media_type_serializers'
12
12
  require 'media_types/serialization/no_serializer_for_content_type'
13
+ require 'media_types/serialization/base'
13
14
  require 'media_types/serialization/wrapper/html_wrapper'
14
- require 'media_types/serialization/wrapper/media_wrapper'
15
15
 
16
16
  module MediaTypes
17
17
  module Serialization
18
18
 
19
- mattr_accessor :common_suffix, :collect_links_for_collection, :collect_links_for_index
19
+ mattr_accessor :common_suffix, :collect_links_for_collection, :collect_links_for_index, :html_wrapper_layout
20
20
 
21
21
  extend ActiveSupport::Concern
22
22
 
@@ -166,7 +166,7 @@ module MediaTypes
166
166
 
167
167
  def wrap_media(serializer, media_view:, media_type:)
168
168
  lambda do |*args, **opts|
169
- Wrapper::MediaWrapper.new(
169
+ serializer.wrap(
170
170
  serializer.new(*args, media_type: media_type, view: media_view, **opts),
171
171
  view: media_view
172
172
  )
@@ -2,17 +2,19 @@
2
2
 
3
3
  require 'uri'
4
4
 
5
- require 'media_types/serialization/mime_type_support'
6
- require 'media_types/serialization/migrations_support'
7
-
8
5
  require 'http_headers/link'
9
6
  require 'http_headers/utils/list'
10
7
 
8
+ require 'media_types/serialization/mime_type_support'
9
+ require 'media_types/serialization/migrations_support'
10
+ require 'media_types/serialization/wrapper_support'
11
+
11
12
  module MediaTypes
12
13
  module Serialization
13
14
  class Base
14
15
  include MimeTypeSupport
15
16
  include MigrationsSupport
17
+ include WrapperSupport
16
18
 
17
19
  attr_accessor :serializable
18
20
 
@@ -26,12 +28,14 @@ module MediaTypes
26
28
 
27
29
  def to_link_header
28
30
  entries = header_links(view: current_view).each_with_index.map do |(rel, opts), index|
31
+ next unless opts.is_a?(String) || opts.try(:[], :href)
29
32
  href = opts.is_a?(String) ? opts : opts.delete(:href)
30
33
  parameters = { rel: rel }.merge(opts.is_a?(String) ? {} : opts)
34
+
31
35
  HttpHeaders::Link::Entry.new("<#{href}>", index: index, parameters: parameters)
32
- end
33
- return nil unless entries.present?
36
+ end.compact
34
37
 
38
+ return nil unless entries.present?
35
39
  HttpHeaders::Utils::List.to_header(entries)
36
40
  end
37
41
 
@@ -6,7 +6,7 @@ module MediaTypes
6
6
  def initialize(given, supported)
7
7
  super format(
8
8
  'Unable to serialize to requested Content-Type: %<given>s. I can give you: %<supported>s',
9
- given: given.inspect,
9
+ given: Array(given).map(&:to_s).inspect,
10
10
  supported: supported.map(&:to_s)
11
11
  )
12
12
  end
@@ -1,5 +1,5 @@
1
1
  module MediaTypes
2
2
  module Serialization
3
- VERSION = '0.4.0'
3
+ VERSION = '0.5.0'
4
4
  end
5
5
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'media_types/serialization/wrapper/root_key'
4
3
  require 'media_types/serialization/wrapper/html_wrapper'
5
- require 'media_types/serialization/wrapper/media_wrapper'
6
4
  require 'media_types/serialization/wrapper/media_object_wrapper'
7
5
  require 'media_types/serialization/wrapper/media_index_wrapper'
8
6
  require 'media_types/serialization/wrapper/media_collection_wrapper'
@@ -5,26 +5,27 @@ require 'delegate'
5
5
  require 'action_controller'
6
6
 
7
7
  require 'media_types/serialization/base'
8
- require 'media_types/serialization/wrapper/root_key'
9
8
 
10
9
  module MediaTypes
11
10
  module Serialization
12
11
  module Wrapper
13
- class HtmlWrapper < DelegateClass(Base)
12
+ class HtmlWrapper < SimpleDelegator
14
13
 
15
14
  delegate :to_s, to: :to_html
16
15
  delegate :class, to: :__getobj__
17
16
 
18
17
  def initialize(serializer, view: nil, **render_options)
19
- super serializer
18
+ __setobj__ serializer
19
+
20
20
  self.view = view
21
21
  self.render_options = render_options
22
22
  end
23
23
 
24
24
  def to_html
25
25
  return super if __getobj__.respond_to?(:to_html)
26
+
26
27
  ActionController::Base.render(
27
- 'serializers/wrapper/html_wrapper',
28
+ ::MediaTypes::Serialization.html_wrapper_layout || 'serializers/wrapper/html_wrapper',
28
29
  assigns: {
29
30
  serializer: self,
30
31
  view: view,
@@ -5,43 +5,44 @@ require 'delegate'
5
5
  require 'active_support/core_ext/string/inflections'
6
6
 
7
7
  require 'media_types/serialization/base'
8
- require 'media_types/serialization/wrapper/root_key'
9
8
 
10
9
  module MediaTypes
11
10
  module Serialization
12
11
  module Wrapper
13
- class MediaCollectionWrapper < DelegateClass(Base)
12
+ class MediaCollectionWrapper < SimpleDelegator
14
13
 
15
14
  delegate :to_json, to: :to_hash
16
15
  delegate :class, to: :__getobj__
17
16
 
18
17
  def initialize(serializer)
19
- super serializer
18
+ __setobj__ serializer
20
19
  end
21
20
 
22
21
  def to_hash
23
- { Wrapper::RootKey.new(__getobj__.class).pluralize => {
24
- '_embedded': auto_wrap_serializable.map(&method(:item_hash)),
25
- '_links': extract_links
26
- } }
22
+ {
23
+ root_key => {
24
+ '_embedded': wrapped_serializable.map(&method(:item_hash)),
25
+ '_links': extract_links
26
+ }
27
+ }
27
28
  end
28
29
  alias to_h to_hash
29
30
 
30
31
  def header_links(view: current_view)
31
- return __getobj__.send(:header_links, view: view) if serializable && ::MediaTypes::Serialization.collect_links_for_collection
32
+ return __getobj__.send(:header_links, view: view) if ::MediaTypes::Serialization.collect_links_for_collection
32
33
  {}
33
34
  end
34
35
 
35
36
  protected
36
37
 
37
38
  def extract_links(view: current_view)
38
- return __getobj__.send(:extract_links, view: view) if serializable && ::MediaTypes::Serialization.collect_links_for_collection
39
+ return __getobj__.send(:extract_links, view: view) if ::MediaTypes::Serialization.collect_links_for_collection
39
40
  {}
40
41
  end
41
42
 
42
- private
43
-
44
- def auto_wrap_serializable
43
+ def wrapped_serializable
44
+ return __getobj__.wrapped_serializable if __getobj__.respond_to?(:wrapped_serializable)
45
+ return [serializable] if serializable.is_a?(::Hash)
45
46
  Array(serializable)
46
47
  end
47
48
 
@@ -50,6 +51,14 @@ module MediaTypes
50
51
  set(item).send(:to_hash)
51
52
  end
52
53
  end
54
+
55
+ def root_key(view: current_view)
56
+ __getobj__.class.root_key(view: view)
57
+ end
58
+
59
+ def current_view
60
+ __getobj__.send(:current_view)
61
+ end
53
62
  end
54
63
  end
55
64
  end
@@ -5,43 +5,39 @@ require 'delegate'
5
5
  require 'active_support/core_ext/string/inflections'
6
6
 
7
7
  require 'media_types/serialization/base'
8
- require 'media_types/serialization/wrapper/root_key'
9
8
 
10
9
  module MediaTypes
11
10
  module Serialization
12
11
  module Wrapper
13
- class MediaIndexWrapper < DelegateClass(Base)
12
+ class MediaIndexWrapper < SimpleDelegator
14
13
 
15
14
  delegate :to_json, to: :to_hash
16
15
  delegate :class, to: :__getobj__
17
16
 
18
17
  def initialize(serializer)
19
- super serializer
18
+ __setobj__ serializer
20
19
  end
21
20
 
22
21
  def to_hash
23
- { Wrapper::RootKey.new(__getobj__.class).pluralize => {
24
- '_index': auto_wrap_serializable.map(&method(:item_hash)),
25
- '_links': extract_links
26
- } }
22
+ {
23
+ root_key => {
24
+ '_index': wrapped_serializable.map(&method(:item_hash)),
25
+ '_links': extract_links
26
+ }
27
+ }
27
28
  end
28
29
  alias to_h to_hash
29
30
 
30
31
  def header_links(view: current_view)
31
- return __getobj__.send(:header_links, view: view) if serializable && ::MediaTypes::Serialization.collect_links_for_index
32
+ return __getobj__.send(:header_links, view: view) if ::MediaTypes::Serialization.collect_links_for_index
32
33
  {}
33
34
  end
34
35
 
35
36
  protected
36
37
 
37
- def extract_links(view: current_view)
38
- return __getobj__.send(:extract_links, view: view) if serializable && ::MediaTypes::Serialization.collect_links_for_index
39
- {}
40
- end
41
-
42
- private
43
-
44
- def auto_wrap_serializable
38
+ def wrapped_serializable
39
+ return __getobj__.wrapped_serializable if __getobj__.respond_to?(:wrapped_serializable)
40
+ return [serializable] if serializable.is_a?(::Hash)
45
41
  Array(serializable)
46
42
  end
47
43
 
@@ -50,6 +46,19 @@ module MediaTypes
50
46
  set(item).send(:extract_self)
51
47
  end
52
48
  end
49
+
50
+ def extract_links(view: current_view)
51
+ return __getobj__.send(:extract_links, view: view) if ::MediaTypes::Serialization.collect_links_for_index
52
+ {}
53
+ end
54
+
55
+ def root_key(view: current_view)
56
+ __getobj__.class.root_key(view: view)
57
+ end
58
+
59
+ def current_view
60
+ __getobj__.send(:current_view)
61
+ end
53
62
  end
54
63
  end
55
64
  end
@@ -5,45 +5,59 @@ require 'delegate'
5
5
  require 'active_support/core_ext/string/inflections'
6
6
 
7
7
  require 'media_types/serialization/base'
8
- require 'media_types/serialization/wrapper/root_key'
9
8
 
10
9
  module MediaTypes
11
10
  module Serialization
12
11
  module Wrapper
13
- class MediaObjectWrapper < DelegateClass(Base)
12
+ class MediaObjectWrapper < SimpleDelegator
14
13
 
15
14
  delegate :to_json, to: :to_hash
16
15
  delegate :class, to: :__getobj__
17
16
 
17
+ mattr_accessor :auto_unwrap_klazzes
18
+
19
+ self.auto_unwrap_klazzes = [Array, defined?(ActiveRecord) ? ActiveRecord::Relation : nil].compact
20
+
18
21
  def initialize(serializer)
19
- super serializer
22
+ __setobj__ serializer
20
23
  end
21
24
 
22
25
  def to_hash
23
- unwrapped = auto_unwrap_serializable.tap { |u| set(u) }
24
- { RootKey.new(__getobj__.class).singularize => unwrapped && super || nil }
26
+ set unwrapped_serializable
27
+ { root_key => serializable && super || nil }
25
28
  end
29
+
26
30
  alias to_h to_hash
27
31
 
28
32
  def header_links(view: current_view)
29
- return __getobj__.send(:header_links, view: view) if serializable
30
- {}
33
+ __getobj__.send(:header_links, view: view)
34
+ end
35
+
36
+ def inspect
37
+ "#{__getobj__.inspect} (wrapped by MediaObjectWrapper #{self.object_id})"
31
38
  end
32
39
 
33
40
  protected
34
41
 
42
+ def unwrapped_serializable
43
+ return __getobj__.unwrapped_serializable if __getobj__.respond_to?(:unwrapped_serializable)
44
+ auto_unwrap_klazzes.any? { |klazz| serializable.is_a?(klazz) } ? serializable.first : serializable
45
+ end
46
+
35
47
  def extract_links(view: current_view)
36
- return __getobj__.send(:extract_links, view: view) if serializable
37
- {}
48
+ __getobj__.send(:extract_links, view: view)
38
49
  end
39
50
 
40
- private
51
+ def root_key(view: current_view)
52
+ __getobj__.class.root_key(view: view)
53
+ end
41
54
 
42
- AUTO_UNWRAP_KLAZZES = [Array, defined?(ActiveRecord) ? ActiveRecord::Relation : nil].compact.freeze
55
+ def set(new_serializable)
56
+ __getobj__.send(:set, new_serializable)
57
+ end
43
58
 
44
- def auto_unwrap_serializable
45
- return serializable unless AUTO_UNWRAP_KLAZZES.any? { |klazz| serializable.is_a?(klazz) }
46
- serializable.first
59
+ def current_view
60
+ __getobj__.send(:current_view)
47
61
  end
48
62
  end
49
63
  end
@@ -0,0 +1,38 @@
1
+ require 'active_support/concern'
2
+
3
+ require 'media_types/views'
4
+ require 'media_types/serialization/wrapper'
5
+
6
+ module MediaTypes
7
+ module Serialization
8
+ module WrapperSupport
9
+ extend ActiveSupport::Concern
10
+
11
+ AUTO_WRAPPER_MAPPING = {
12
+ ::MediaTypes::INDEX_VIEW => ::MediaTypes::Serialization::Wrapper::MediaIndexWrapper,
13
+ ::MediaTypes::COLLECTION_VIEW => ::MediaTypes::Serialization::Wrapper::MediaCollectionWrapper,
14
+ ::MediaTypes::CREATE_VIEW => ::MediaTypes::Serialization::Wrapper::MediaObjectWrapper,
15
+ nil => ::MediaTypes::Serialization::Wrapper::MediaObjectWrapper
16
+ }.freeze
17
+
18
+ DEFAULT_WRAPPER = ::MediaTypes::Serialization::Wrapper::MediaObjectWrapper
19
+
20
+ class_methods do
21
+ def wrap(serializer, view: nil)
22
+ wrapper = AUTO_WRAPPER_MAPPING.fetch(String(view)) { DEFAULT_WRAPPER }
23
+ wrapper.new(serializer)
24
+ end
25
+
26
+ def root_key(view:)
27
+ chomped = name.demodulize.chomp(::MediaTypes::Serialization.common_suffix || 'Serializer')
28
+ base = (chomped.presence || parent.name.demodulize).underscore
29
+ collection_view?(view) ? base.pluralize : base.singularize
30
+ end
31
+
32
+ def collection_view?(view)
33
+ view == ::MediaTypes::INDEX_VIEW || view == ::MediaTypes::COLLECTION_VIEW
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,48 +1,48 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "media_types/serialization/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "media_types-serialization"
8
- spec.version = MediaTypes::Serialization::VERSION
9
- spec.authors = ["Derk-Jan Karrenbeld"]
10
- spec.email = ["derk-jan@xpbytes.com"]
11
-
12
- spec.summary = 'Add media types supported serialization using your favourite serializer'
13
- spec.homepage = 'https://github.com/XPBytes/media_types-serialization'
14
- spec.license = 'MIT'
15
-
16
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
- # to allow pushing to a single host or delete this section to allow pushing to any host.
18
- if spec.respond_to?(:metadata)
19
- # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
20
-
21
- spec.metadata["homepage_uri"] = spec.homepage
22
- spec.metadata["source_code_uri"] = spec.homepage
23
- spec.metadata["changelog_uri"] = spec.homepage + '/CHANGELOG.md'
24
- else
25
- raise "RubyGems 2.0 or newer is required to protect against " \
26
- "public gem pushes."
27
- end
28
-
29
- # Specify which files should be added to the gem when it is released.
30
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
32
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
- end
34
- spec.bindir = "exe"
35
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
- spec.require_paths = ["lib"]
37
-
38
- spec.add_dependency 'actionpack', '>= 4.0.0'
39
- spec.add_dependency 'activesupport', '>= 4.0.0'
40
- spec.add_dependency 'media_types', '>= 0.6.0'
41
- spec.add_dependency 'oj', '>= 3.5.0'
42
- spec.add_dependency 'http_headers-accept', '< 1.0.0'
43
- spec.add_dependency 'http_headers-link', '< 1.0.0'
44
-
45
- spec.add_development_dependency "bundler", "~> 2.0"
46
- spec.add_development_dependency "rake", "~> 10.0"
47
- spec.add_development_dependency "minitest", "~> 5.0"
48
- end
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "media_types/serialization/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "media_types-serialization"
8
+ spec.version = MediaTypes::Serialization::VERSION
9
+ spec.authors = ["Derk-Jan Karrenbeld"]
10
+ spec.email = ["derk-jan@xpbytes.com"]
11
+
12
+ spec.summary = 'Add media types supported serialization using your favourite serializer'
13
+ spec.homepage = 'https://github.com/XPBytes/media_types-serialization'
14
+ spec.license = 'MIT'
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
20
+
21
+ spec.metadata["homepage_uri"] = spec.homepage
22
+ spec.metadata["source_code_uri"] = spec.homepage
23
+ spec.metadata["changelog_uri"] = spec.homepage + '/CHANGELOG.md'
24
+ else
25
+ raise "RubyGems 2.0 or newer is required to protect against " \
26
+ "public gem pushes."
27
+ end
28
+
29
+ # Specify which files should be added to the gem when it is released.
30
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+ spec.bindir = "exe"
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ["lib"]
37
+
38
+ spec.add_dependency 'actionpack', '>= 4.0.0'
39
+ spec.add_dependency 'activesupport', '>= 4.0.0'
40
+ spec.add_dependency 'media_types', '>= 0.6.0'
41
+ spec.add_dependency 'oj', '>= 3.5.0'
42
+ spec.add_dependency 'http_headers-accept', '< 1.0.0'
43
+ spec.add_dependency 'http_headers-link', '< 1.0.0'
44
+
45
+ spec.add_development_dependency "bundler", "~> 2.0"
46
+ spec.add_development_dependency "rake", "~> 10.0"
47
+ spec.add_development_dependency "minitest", "~> 5.0"
48
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: media_types-serialization
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derk-Jan Karrenbeld
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-19 00:00:00.000000000 Z
11
+ date: 2019-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -180,8 +180,7 @@ files:
180
180
  - lib/media_types/serialization/wrapper/media_collection_wrapper.rb
181
181
  - lib/media_types/serialization/wrapper/media_index_wrapper.rb
182
182
  - lib/media_types/serialization/wrapper/media_object_wrapper.rb
183
- - lib/media_types/serialization/wrapper/media_wrapper.rb
184
- - lib/media_types/serialization/wrapper/root_key.rb
183
+ - lib/media_types/serialization/wrapper_support.rb
185
184
  - media_types-serialization.gemspec
186
185
  homepage: https://github.com/XPBytes/media_types-serialization
187
186
  licenses:
@@ -205,7 +204,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
204
  - !ruby/object:Gem::Version
206
205
  version: '0'
207
206
  requirements: []
208
- rubygems_version: 3.0.2
207
+ rubyforge_project:
208
+ rubygems_version: 2.7.6
209
209
  signing_key:
210
210
  specification_version: 4
211
211
  summary: Add media types supported serialization using your favourite serializer
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'media_types'
4
-
5
- require 'media_types/serialization/wrapper/media_index_wrapper'
6
- require 'media_types/serialization/wrapper/media_collection_wrapper'
7
- require 'media_types/serialization/wrapper/media_object_wrapper'
8
-
9
- module MediaTypes
10
- module Serialization
11
- module Wrapper
12
- class MediaWrapper
13
-
14
- AUTO_WRAPPER_MAPPING = {
15
- ::MediaTypes::INDEX_VIEW => MediaIndexWrapper,
16
- ::MediaTypes::COLLECTION_VIEW => MediaCollectionWrapper,
17
- ::MediaTypes::CREATE_VIEW => MediaObjectWrapper,
18
- nil => MediaObjectWrapper
19
- }.freeze
20
-
21
- DEFAULT_WRAPPER = MediaObjectWrapper
22
-
23
- class << self
24
- def new(serializer, view: nil)
25
- wrapper = AUTO_WRAPPER_MAPPING.fetch(String(view)) { DEFAULT_WRAPPER }
26
- wrapper.new(serializer)
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'delegate'
4
-
5
- require 'active_support/core_ext/object/blank'
6
- require 'active_support/core_ext/string/inflections'
7
-
8
- module MediaTypes
9
- module Serialization
10
- module Wrapper
11
- class RootKey < DelegateClass(String)
12
- def initialize(klazz)
13
- base = klazz.name.demodulize.chomp(MediaTypes::Serialization.common_suffix || 'Serializer').presence ||
14
- klazz.parent.name.demodulize
15
- super base.underscore
16
- end
17
- end
18
- end
19
- end
20
- end