juso 0.2.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc3dce11d5ba4c7a3ef2ff135c5cb75f88689c78f1b48c7db47beb51bfdb82b8
4
- data.tar.gz: 011ba9b8a7aeed23122681264bfcc0cc02898bf0b56d28f59a344429d3bfbc34
3
+ metadata.gz: 912622622f8b9a6866a505f8ba27a1cc21a3073a59ac364942ce6d997baeb875
4
+ data.tar.gz: 125f56e1649fad476b076457272349a221ec69f38600bc17f62bf0255902a777
5
5
  SHA512:
6
- metadata.gz: e478fc64b56739caf65a103f3f196e185a2a52d36b758641643715aa09f6f5c8fd88f8abd3c471178c06ec2df64f6ef64e87f10fee738d4034d8945c793b15d3
7
- data.tar.gz: f4f1da552903c37ec9fdfc3e92ae34a1d08f463396307c8abea80420464992807f4f94e691023bd5ea5a6312e61a38fbedc2c56cd26ec7a9f7d6fbda69b29927
6
+ metadata.gz: cc04ee74481f9fa92988d4e4457eb40929e670a91c95b07171af2358c5f85a77dbd2af2ba846a0bc1c90da13aca85363fba5060b75255e91373fcf964ee5893c
7
+ data.tar.gz: 7d51bbec1f134665d4f058c666d64616762e8b86b2981fd94eb03af40a638e71d952e42bdaf1a8216342a4ee644da6f57f7ccba8730b0f4dc6f6672e1ae6e0b9
@@ -8,8 +8,10 @@ jobs:
8
8
  timeout-minutes: 10
9
9
 
10
10
  strategy:
11
+ fail-fast: false
11
12
  matrix:
12
- ruby-version: [3.1.0-preview1, 3.0.2, 2.7.4, 2.6.8]
13
+ # ruby-version: [3.1.0-preview1, 3.0.2, 2.7.4, 2.6.8]
14
+ ruby-version: [3.0.2, 2.7.4, 2.6.8]
13
15
 
14
16
  steps:
15
17
  - uses: actions/checkout@v2
@@ -22,3 +24,10 @@ jobs:
22
24
 
23
25
  - name: Run test
24
26
  run: bundle exec rake test
27
+
28
+ - name: Run test (rails)
29
+ env:
30
+ RAILS_TEST: true
31
+ run: |
32
+ bundle exec rails db:setup
33
+ bundle exec rake test
data/.gitignore CHANGED
@@ -6,3 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+
10
+ test/dummy/log/*.log
11
+ test/dummy/db/development.sqlite3
12
+ test/dummy/db/test.sqlite3
data/Gemfile CHANGED
@@ -10,3 +10,6 @@ gem "rake", "~> 13.0"
10
10
  gem "minitest", "~> 5.0"
11
11
 
12
12
  gem "rubocop", "~> 1.7"
13
+
14
+ gem 'sqlite3'
15
+ gem 'json_expressions'
data/Gemfile.lock CHANGED
@@ -1,16 +1,131 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- juso (0.1.0)
4
+ juso (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ actioncable (6.1.4.1)
10
+ actionpack (= 6.1.4.1)
11
+ activesupport (= 6.1.4.1)
12
+ nio4r (~> 2.0)
13
+ websocket-driver (>= 0.6.1)
14
+ actionmailbox (6.1.4.1)
15
+ actionpack (= 6.1.4.1)
16
+ activejob (= 6.1.4.1)
17
+ activerecord (= 6.1.4.1)
18
+ activestorage (= 6.1.4.1)
19
+ activesupport (= 6.1.4.1)
20
+ mail (>= 2.7.1)
21
+ actionmailer (6.1.4.1)
22
+ actionpack (= 6.1.4.1)
23
+ actionview (= 6.1.4.1)
24
+ activejob (= 6.1.4.1)
25
+ activesupport (= 6.1.4.1)
26
+ mail (~> 2.5, >= 2.5.4)
27
+ rails-dom-testing (~> 2.0)
28
+ actionpack (6.1.4.1)
29
+ actionview (= 6.1.4.1)
30
+ activesupport (= 6.1.4.1)
31
+ rack (~> 2.0, >= 2.0.9)
32
+ rack-test (>= 0.6.3)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
35
+ actiontext (6.1.4.1)
36
+ actionpack (= 6.1.4.1)
37
+ activerecord (= 6.1.4.1)
38
+ activestorage (= 6.1.4.1)
39
+ activesupport (= 6.1.4.1)
40
+ nokogiri (>= 1.8.5)
41
+ actionview (6.1.4.1)
42
+ activesupport (= 6.1.4.1)
43
+ builder (~> 3.1)
44
+ erubi (~> 1.4)
45
+ rails-dom-testing (~> 2.0)
46
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
47
+ activejob (6.1.4.1)
48
+ activesupport (= 6.1.4.1)
49
+ globalid (>= 0.3.6)
50
+ activemodel (6.1.4.1)
51
+ activesupport (= 6.1.4.1)
52
+ activerecord (6.1.4.1)
53
+ activemodel (= 6.1.4.1)
54
+ activesupport (= 6.1.4.1)
55
+ activestorage (6.1.4.1)
56
+ actionpack (= 6.1.4.1)
57
+ activejob (= 6.1.4.1)
58
+ activerecord (= 6.1.4.1)
59
+ activesupport (= 6.1.4.1)
60
+ marcel (~> 1.0.0)
61
+ mini_mime (>= 1.1.0)
62
+ activesupport (6.1.4.1)
63
+ concurrent-ruby (~> 1.0, >= 1.0.2)
64
+ i18n (>= 1.6, < 2)
65
+ minitest (>= 5.1)
66
+ tzinfo (~> 2.0)
67
+ zeitwerk (~> 2.3)
9
68
  ast (2.4.2)
69
+ builder (3.2.4)
70
+ concurrent-ruby (1.1.9)
71
+ crass (1.0.6)
72
+ erubi (1.10.0)
73
+ globalid (1.0.0)
74
+ activesupport (>= 5.0)
75
+ i18n (1.8.11)
76
+ concurrent-ruby (~> 1.0)
77
+ json_expressions (0.9.0)
78
+ loofah (2.12.0)
79
+ crass (~> 1.0.2)
80
+ nokogiri (>= 1.5.9)
81
+ mail (2.7.1)
82
+ mini_mime (>= 0.1.1)
83
+ marcel (1.0.2)
84
+ method_source (1.0.0)
85
+ mini_mime (1.1.2)
86
+ mini_portile2 (2.6.1)
10
87
  minitest (5.14.4)
88
+ nio4r (2.5.8)
89
+ nokogiri (1.12.5)
90
+ mini_portile2 (~> 2.6.1)
91
+ racc (~> 1.4)
92
+ nokogiri (1.12.5-arm64-darwin)
93
+ racc (~> 1.4)
94
+ nokogiri (1.12.5-x86_64-linux)
95
+ racc (~> 1.4)
11
96
  parallel (1.21.0)
12
97
  parser (3.0.2.0)
13
98
  ast (~> 2.4.1)
99
+ racc (1.6.0)
100
+ rack (2.2.3)
101
+ rack-test (1.1.0)
102
+ rack (>= 1.0, < 3)
103
+ rails (6.1.4.1)
104
+ actioncable (= 6.1.4.1)
105
+ actionmailbox (= 6.1.4.1)
106
+ actionmailer (= 6.1.4.1)
107
+ actionpack (= 6.1.4.1)
108
+ actiontext (= 6.1.4.1)
109
+ actionview (= 6.1.4.1)
110
+ activejob (= 6.1.4.1)
111
+ activemodel (= 6.1.4.1)
112
+ activerecord (= 6.1.4.1)
113
+ activestorage (= 6.1.4.1)
114
+ activesupport (= 6.1.4.1)
115
+ bundler (>= 1.15.0)
116
+ railties (= 6.1.4.1)
117
+ sprockets-rails (>= 2.0.0)
118
+ rails-dom-testing (2.0.3)
119
+ activesupport (>= 4.2.0)
120
+ nokogiri (>= 1.6)
121
+ rails-html-sanitizer (1.4.2)
122
+ loofah (~> 2.3)
123
+ railties (6.1.4.1)
124
+ actionpack (= 6.1.4.1)
125
+ activesupport (= 6.1.4.1)
126
+ method_source
127
+ rake (>= 0.13)
128
+ thor (~> 1.0)
14
129
  rainbow (3.0.0)
15
130
  rake (13.0.6)
16
131
  regexp_parser (2.1.1)
@@ -27,7 +142,22 @@ GEM
27
142
  rubocop-ast (1.13.0)
28
143
  parser (>= 3.0.1.1)
29
144
  ruby-progressbar (1.11.0)
145
+ sprockets (4.0.2)
146
+ concurrent-ruby (~> 1.0)
147
+ rack (> 1, < 3)
148
+ sprockets-rails (3.4.1)
149
+ actionpack (>= 5.2)
150
+ activesupport (>= 5.2)
151
+ sprockets (>= 3.0.0)
152
+ sqlite3 (1.4.2)
153
+ thor (1.1.0)
154
+ tzinfo (2.0.4)
155
+ concurrent-ruby (~> 1.0)
30
156
  unicode-display_width (2.1.0)
157
+ websocket-driver (0.7.5)
158
+ websocket-extensions (>= 0.1.0)
159
+ websocket-extensions (0.1.5)
160
+ zeitwerk (2.5.1)
31
161
 
32
162
  PLATFORMS
33
163
  arm64-darwin-20
@@ -35,10 +165,13 @@ PLATFORMS
35
165
  x86_64-linux
36
166
 
37
167
  DEPENDENCIES
168
+ json_expressions
38
169
  juso!
39
170
  minitest (~> 5.0)
171
+ rails (~> 6.1.4)
40
172
  rake (~> 13.0)
41
173
  rubocop (~> 1.7)
174
+ sqlite3
42
175
 
43
176
  BUNDLED WITH
44
177
  2.2.22
data/README.md CHANGED
@@ -7,6 +7,16 @@
7
7
  Juso is simple, fast and explicit JSON Serializer.
8
8
  Juso means 13 (thirteen) in Japanese.
9
9
 
10
+ ## Motivation
11
+
12
+ #### Japanese
13
+
14
+ Juso は juso というメソッドを定義することで JSON 化が可能になります。Ruby の Hash や Array を用いて定義すれば良いので、覚えることが非常に少ないことが特徴です。また、暗黙的な挙動で非公開にすべき属性が公開されることを防ぎます。
15
+
16
+ Ruby on Rails においては Model のクラスにそのまま定義することができるため、初期の導入としてはシンプルでわかりやすいです。[^1]
17
+
18
+ [^1]: as_json メソッドで頑張ることもできますが、より宣言的で分かりやすいはずです
19
+
10
20
  ## Installation
11
21
 
12
22
  Add this line to your application's Gemfile:
@@ -26,7 +36,7 @@ Or install it yourself as:
26
36
  ## Usage
27
37
 
28
38
  1. Include `Juso::Serializable` to your class.
29
- 2. Define as_juso_json(context) method.
39
+ 2. Define juso(context) method.
30
40
  3. Use Juso.generate(object) method to generate json.
31
41
 
32
42
  ```ruby
@@ -35,7 +45,7 @@ class User < ApplicationRecord
35
45
 
36
46
  # ...
37
47
 
38
- def as_juso_json(context)
48
+ def juso(context)
39
49
  {
40
50
  id: id,
41
51
  nickname: nickname,
@@ -50,7 +60,7 @@ class Team < ApplicationRecord
50
60
 
51
61
  # ...
52
62
 
53
- def as_juso_json(context)
63
+ def juso(context)
54
64
  {
55
65
  id: id,
56
66
  name: name,
@@ -70,17 +80,60 @@ Juso.generate(team)
70
80
 
71
81
  #### Japanese
72
82
 
73
- as_juso_json メソッドは以下のインスタンスしか返してはいけません
83
+ juso メソッドは以下のインスタンスしか返してはいけません
74
84
 
75
85
  - Numeric Class
76
86
  - String Class
77
- - Null Class
87
+ - Nil Class
88
+ - True Class
89
+ - False Class
78
90
  - Hash Class
79
91
  - Array Class
80
- - Juso::Serializable をinclude したクラス
92
+ - Juso::Serializable を include したクラス
81
93
  - Date / DateTime / ActiveSupport::TimeWithZone
82
94
 
83
- 再帰的にjusoの処理が適用されるため、Arrayの要素やHashのvalueも同様のルールが適用されます
95
+ 再帰的に juso の処理が適用されるため、Array の要素や Hash value も同様のルールが適用されます
96
+
97
+ ### Juso::Context
98
+
99
+ #### Japanese
100
+
101
+ juso メソッドには Context オブジェクトが渡されます。これによって、Juso.generate から各 juso メソッドにシリアライズのオプションを伝播させることができます
102
+
103
+ ### Juso.wrap
104
+
105
+ ```ruby
106
+ class UserSerializer
107
+ include Juso::Serializable
108
+
109
+ # ...
110
+
111
+ def juso(context)
112
+ {
113
+ id: @user.id,
114
+ posts: Juso.wrap(@user.posts, PostSerializer), # use PostSerializer#juso method. Each post passes into PostSerializer object.
115
+ team: @user.team, # use Team#juso method
116
+ }
117
+ end
118
+ end
119
+
120
+ class PostSerializer
121
+ include Juso::Serializable
122
+
123
+ def initialize(post)
124
+ @post = post
125
+ end
126
+
127
+ def juso(context)
128
+ # do something with @post...
129
+ end
130
+ end
131
+ ```
132
+
133
+ #### Japanese
134
+
135
+ Juso.wrap(object, serializable_class) ユーティリティを使うことで、特定のクラスに処理を委譲できます。
136
+ コード例だと、 @user.posts は Post の ActiveRecord::Relation を返しますが、通常であれば Post インスタンスの juso メソッドが使われるのに対して、各 Post インスタンスを PostSerializer でラップします。PostSerializer#juso メソッドが呼ばれることになります。
84
137
 
85
138
  ## Development
86
139
 
data/Rakefile CHANGED
@@ -6,11 +6,17 @@ require "rake/testtask"
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "test"
8
8
  t.libs << "lib"
9
- t.test_files = FileList["test/**/*_test.rb"]
10
- end
11
9
 
12
- require "rubocop/rake_task"
10
+ files = FileList["test/juso_test.rb"]
11
+
12
+ if ENV['RAILS_TEST']
13
+ files << 'test/rails_test.rb'
14
+ end
15
+
16
+ t.test_files = files
17
+ end
13
18
 
14
- RuboCop::RakeTask.new
19
+ # require "rubocop/rake_task"
20
+ # RuboCop::RakeTask.new
15
21
 
16
- task default: %i[test rubocop]
22
+ task default: %i[test]
@@ -90,13 +90,11 @@ end
90
90
  # --- Juso serializers ---
91
91
 
92
92
  require "juso"
93
- require 'active_record' # hack for CollectionProxy
94
- Juso.reset_collection_classes
95
93
 
96
94
  class Comment
97
95
  include ::Juso::Serializable
98
96
 
99
- def as_juso_json(context)
97
+ def juso(context)
100
98
  {id: id, body: body}
101
99
  end
102
100
  end
@@ -104,7 +102,7 @@ end
104
102
  class Post
105
103
  include ::Juso::Serializable
106
104
 
107
- def as_juso_json(context)
105
+ def juso(context)
108
106
  {id: id, body: body, commenter_names: commenter_names, comments: comments}
109
107
  end
110
108
  end
data/juso.gemspec CHANGED
@@ -34,4 +34,6 @@ Gem::Specification.new do |spec|
34
34
 
35
35
  # For more information and examples about making a new gem, checkout our
36
36
  # guide at: https://bundler.io/guides/creating_gem.html
37
+
38
+ spec.add_development_dependency "rails", "~> 6.1.4"
37
39
  end
data/lib/juso/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Juso
4
- VERSION = "0.2.0"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/juso.rb CHANGED
@@ -9,63 +9,77 @@ module Juso
9
9
  class Error < StandardError; end
10
10
 
11
11
  module Serializable
12
- def as_juso_json(_)
12
+ def juso(_)
13
13
  nil
14
14
  end
15
15
  end
16
16
 
17
- # Juso Context is serializer context
18
- # xxxxx
17
+ # Juso::Context is serializer context
19
18
  class Context
20
- def initialize(serializer_type: :default)
21
- @serializer_type = serializer_type.to_sym
19
+ DEFAULT_OPTS = {}.freeze
20
+
21
+ def initialize(serializer: :default, options: DEFAULT_OPTS)
22
+ @serializer = serializer
23
+ @options = options
22
24
  end
23
25
 
24
- attr_reader :serializer_type
26
+ attr_reader :serializer, :options
25
27
  end
26
28
 
29
+ # Juso.generate generates json string
27
30
  def self.generate(object, context: Context.new)
28
- JSON.fast_generate(_generate(object, context))
31
+ JSON.fast_generate(_g(object, context))
29
32
  end
30
33
 
31
34
  # generate returns hash (as json)
32
- def self._generate(object, context)
35
+ def self._g(object, context)
33
36
  case object
34
- when nil, Numeric, String
37
+ when nil, Numeric, String, true, false
35
38
  return object
36
39
  when Hash
37
40
  return object.each_with_object({}) do |(k, v), acc|
38
- acc[k] = _generate(v, context)
41
+ acc[k] = _g(v, context)
39
42
  end
40
43
  when Serializable
41
- # respond_to?(:as_juso_json) のほうが良い可能性ある?
42
- return _generate(object.as_juso_json(context), context)
44
+ # respond_to?(:juso) のほうが良い可能性ある?
45
+ return _g(object.juso(context), context)
43
46
  when *collection_classes
44
- return object.to_a.map { |o| _generate(o, context) }
47
+ return object.to_a.map { |o| _g(o, context) }
45
48
  when *date_classes
46
49
  return object.iso8601
47
50
  else
48
- # TODO: fallback to respond_to?(:as_juso_json) and warn?
51
+ # TODO: fallback to respond_to?(:juso) and warn?
49
52
 
50
53
  raise Error.new("cannot serialize object: #{object}. you must include Juso::Serializable")
51
54
  end
52
55
  end
53
56
 
57
+ # Juso.wrap is utility for wrapping object with Juso::Serializable class
58
+ def self.wrap(object, klass)
59
+ if collection_classes.any? { |arrayish| object.is_a?(arrayish) }
60
+ object.to_a.map { |o| klass.new(o) }
61
+ else
62
+ klass.new(object)
63
+ end
64
+ end
65
+
54
66
  def self.collection_classes
55
- @collection_classes
67
+ @collection_classes ||= default_collection_classes
56
68
  end
57
69
 
58
- def self.reset_collection_classes
59
- @collection_classes =
60
- if defined?(ActiveRecord)
61
- [Array, ActiveRecord::Relation, ActiveRecord::Associations::CollectionProxy]
62
- else
63
- [Array]
64
- end
70
+ def self.default_collection_classes
71
+ if defined?(ActiveRecord)
72
+ [Array, ActiveRecord::Relation]
73
+ else
74
+ [Array]
75
+ end
65
76
  end
66
77
 
67
78
  def self.date_classes
68
- # TODO: FIX / memorize
79
+ @date_classes ||= default_date_classes
80
+ end
81
+
82
+ def self.default_date_classes
69
83
  if defined?(ActiveSupport::TimeWithZone)
70
84
  [Date, DateTime, ActiveSupport::TimeWithZone]
71
85
  else
@@ -73,5 +87,5 @@ module Juso
73
87
  end
74
88
  end
75
89
 
76
- reset_collection_classes
90
+ private_class_method :default_collection_classes, :default_date_classes, :_g
77
91
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: juso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ykpythemind
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-23 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.1.4
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 6.1.4
13
27
  description: juso is simple json serializer for web application
14
28
  email:
15
29
  - yukibukiyou@gmail.com