ree_lib 1.0.64 → 1.0.66

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: 58dcd5d4f8eeefdbea1dc995ea2e76734a8dccc6a913354085453ca9a0ddd72e
4
- data.tar.gz: 1d29d9be3027f3d57e3502e6269ac3cd455e50e5ecdf4b17ea73877b15379423
3
+ metadata.gz: e4afa1450a6827106e39ef7e907de9ce4f490a2cc323bbc59eca1c5cf7386b69
4
+ data.tar.gz: 2a7e3858a80590ad65ce462f77d61f1e5d87435fdf9b5528c626ed41a573cb5c
5
5
  SHA512:
6
- metadata.gz: 35b733d5bcaf9f7f837d212c7279c77044f29e11b5e48d0480a879180497f77805b3aa0bf5e17a8b2b1aa991f769a1452fad291d6895436d8d1eca6e9a6a4fb6
7
- data.tar.gz: '08ec8fe4b53aceff584a515ca820484e59bfa387ae3d5f9c9d21fcdf73afa018d777882f40cab8e6f835fc5eb80ca941977f211614aa0005e10ebcea9fc333c9'
6
+ metadata.gz: 6a2d3070cbe58af3289dd89da27004955d4689a2b32758b7dd123288e6fabcc1915571ee6b353cd8edd0beaef8402f9668bf8034742a7ab30359d26b1f7828a3
7
+ data.tar.gz: 3eb4943530aa4e658f091ce8d8314032b9b5381828ec04e82686ecea3ec2a6481d56783eb19a8d86a943d3108a846632ff0903ec2a28b164734792f9e20322ae
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree_lib (1.0.64)
4
+ ree_lib (1.0.66)
5
5
  binding_of_caller (~> 1.0.0)
6
6
  i18n (~> 1.12.0)
7
7
  loofah (~> 2.18.0)
@@ -2,8 +2,10 @@ module ReeDao
2
2
  class Association
3
3
  include Ree::LinkDSL
4
4
 
5
+ link :demodulize, from: :ree_string
5
6
  link :group_by, from: :ree_array
6
7
  link :index_by, from: :ree_array
8
+ link :underscore, from: :ree_string
7
9
 
8
10
  attr_reader :parent, :parent_dao_name, :list, :global_opts
9
11
 
@@ -21,8 +23,8 @@ module ReeDao
21
23
  Ksplat[RestKeys => Any],
22
24
  Optblock => Array
23
25
  )
24
- def load(assoc_type, assoc_name, **opts, &block)
25
- load_association(assoc_type, assoc_name, **opts, &block)
26
+ def load(assoc_type, assoc_name, **__opts, &block)
27
+ load_association(assoc_type, assoc_name, **__opts, &block)
26
28
  end
27
29
 
28
30
  def handle_field(field_proc)
@@ -35,19 +37,30 @@ module ReeDao
35
37
  Ksplat[RestKeys => Any],
36
38
  Optblock => Nilor[Array]
37
39
  )
38
- def load_association(assoc_type, assoc_name, **opts, &block)
39
- opts[:autoload_children] ||= false
40
+ def load_association(assoc_type, assoc_name, **__opts, &block)
41
+ __opts[:autoload_children] ||= false
40
42
 
41
43
  assoc_index = load_association_by_type(
42
44
  assoc_type,
43
45
  assoc_name,
44
- **opts
46
+ **__opts
45
47
  )
46
48
 
47
- dao = find_dao(assoc_name, parent, opts[:scope])
48
- dao_name = dao.first_source_table
49
+ dao = find_dao(assoc_name, parent, __opts[:scope])
49
50
 
50
- process_block(assoc_index, opts[:autoload_children], opts[:to_dto], dao_name, &block) if block_given?
51
+ dao_name = if dao
52
+ dao.first_source_table
53
+ elsif __opts[:scope].is_a?(Array)
54
+ name = underscore(demodulize(__opts[:scope].first.class.name))
55
+
56
+ if name.end_with?("s")
57
+ "#{name}es"
58
+ else
59
+ "#{name}s"
60
+ end
61
+ end
62
+
63
+ process_block(assoc_index, __opts[:autoload_children], __opts[:to_dto], dao_name, &block) if block_given?
51
64
 
52
65
  list
53
66
  end
@@ -57,17 +70,17 @@ module ReeDao
57
70
  Symbol,
58
71
  Ksplat[RestKeys => Any] => Any
59
72
  )
60
- def load_association_by_type(type, assoc_name, **opts)
73
+ def load_association_by_type(type, assoc_name, **__opts)
61
74
  case type
62
75
  when :belongs_to
63
76
  one_to_one(
64
77
  parent_dao_name,
65
78
  assoc_name,
66
79
  list,
67
- scope: opts[:scope],
68
- primary_key: opts[:primary_key],
69
- foreign_key: opts[:foreign_key],
70
- setter: opts[:setter],
80
+ scope: __opts[:scope],
81
+ primary_key: __opts[:primary_key],
82
+ foreign_key: __opts[:foreign_key],
83
+ setter: __opts[:setter],
71
84
  reverse: false
72
85
  )
73
86
  when :has_one
@@ -75,11 +88,11 @@ module ReeDao
75
88
  parent_dao_name,
76
89
  assoc_name,
77
90
  list,
78
- scope: opts[:scope],
79
- primary_key: opts[:primary_key],
80
- foreign_key: opts[:foreign_key],
81
- to_dto: opts[:to_dto],
82
- setter: opts[:setter],
91
+ scope: __opts[:scope],
92
+ primary_key: __opts[:primary_key],
93
+ foreign_key: __opts[:foreign_key],
94
+ to_dto: __opts[:to_dto],
95
+ setter: __opts[:setter],
83
96
  reverse: true
84
97
  )
85
98
  when :has_many
@@ -87,11 +100,11 @@ module ReeDao
87
100
  parent_dao_name,
88
101
  assoc_name,
89
102
  list,
90
- scope: opts[:scope],
91
- primary_key: opts[:primary_key],
92
- foreign_key: opts[:foreign_key],
93
- to_dto: opts[:to_dto],
94
- setter: opts[:setter]
103
+ scope: __opts[:scope],
104
+ primary_key: __opts[:primary_key],
105
+ foreign_key: __opts[:foreign_key],
106
+ to_dto: __opts[:to_dto],
107
+ setter: __opts[:setter]
95
108
  )
96
109
  end
97
110
  end
@@ -124,9 +137,9 @@ module ReeDao
124
137
  autoload_children,
125
138
  **global_opts
126
139
  ).instance_exec(assoc_list, &block)
127
- threads[:association_threads].map do |association, assoc_type, assoc_name, opts, block|
140
+ threads[:association_threads].map do |association, assoc_type, assoc_name, __opts, block|
128
141
  Thread.new do
129
- association.load(assoc_type, assoc_name, **opts, &block)
142
+ association.load(assoc_type, assoc_name, **__opts, &block)
130
143
  end
131
144
  end.map(&:join)
132
145
 
@@ -192,6 +205,7 @@ module ReeDao
192
205
  setter: setter,
193
206
  reverse: reverse,
194
207
  primary_key: primary_key,
208
+ foreign_key: foreign_key,
195
209
  to_dto: to_dto
196
210
  )
197
211
 
@@ -243,6 +257,7 @@ module ReeDao
243
257
  assoc_name,
244
258
  setter: setter,
245
259
  primary_key: primary_key,
260
+ foreign_key: foreign_key,
246
261
  to_dto: to_dto,
247
262
  multiple: true
248
263
  )
@@ -256,13 +271,14 @@ module ReeDao
256
271
  Symbol,
257
272
  Kwargs[
258
273
  primary_key: Nilor[Symbol],
274
+ foreign_key: Nilor[Symbol],
259
275
  reverse: Nilor[Bool],
260
276
  setter: Nilor[Or[Symbol, Proc]],
261
277
  to_dto: Nilor[Proc],
262
278
  multiple: Bool
263
279
  ] => Any
264
280
  )
265
- def populate_association(list, association_index, assoc_name, primary_key: nil, reverse: nil, setter: nil, to_dto: nil, multiple: false)
281
+ def populate_association(list, association_index, assoc_name, primary_key: nil, foreign_key: nil, reverse: nil, setter: nil, to_dto: nil, multiple: false)
266
282
  assoc_setter = if setter
267
283
  setter
268
284
  else
@@ -290,7 +306,11 @@ module ReeDao
290
306
  key = if reverse.nil?
291
307
  primary_key
292
308
  else
293
- reverse ? primary_key : "#{assoc_name}_id"
309
+ if reverse
310
+ primary_key
311
+ else
312
+ foreign_key ? foreign_key : "#{assoc_name}_id"
313
+ end
294
314
  end
295
315
 
296
316
  value = association_index[item.send(key)]
@@ -330,6 +350,7 @@ module ReeDao
330
350
  return dao_from_name if dao_from_name
331
351
 
332
352
  raise ArgumentError, "can't find DAO for :#{assoc_name}, provide correct scope or association name" if scope.nil?
353
+ return nil if scope.is_a?(Array)
333
354
 
334
355
  table_name = scope.first_source_table
335
356
  dao_from_scope = parent.instance_variable_get("@#{table_name}")
@@ -14,8 +14,13 @@ module ReeDao
14
14
  @parent_dao_name = parent_dao_name
15
15
  @autoload_children = autoload_children
16
16
 
17
- raise ArgumentError.new("you can't use both :only and :except arguments at the same time") if @only && @except
17
+ if @only && @except
18
+ shared_keys = @only.intersection(@except)
18
19
 
20
+ if shared_keys.size > 0
21
+ raise ArgumentError.new("you can't use both :only and :except for #{shared_keys.map { "\"#{_1}\"" }.join(", ")} keys")
22
+ end
23
+ end
19
24
 
20
25
  if !self.class.sync_mode?
21
26
  @assoc_threads = []
@@ -40,8 +45,8 @@ module ReeDao
40
45
  Nilor[Proc, Sequel::Dataset],
41
46
  Optblock => Any
42
47
  )
43
- def belongs_to(assoc_name, opts = nil, &block)
44
- association(__method__, assoc_name, opts, &block)
48
+ def belongs_to(assoc_name, __opts = nil, &block)
49
+ association(__method__, assoc_name, __opts, &block)
45
50
  end
46
51
 
47
52
  contract(
@@ -49,8 +54,8 @@ module ReeDao
49
54
  Nilor[Proc, Sequel::Dataset],
50
55
  Optblock => Any
51
56
  )
52
- def has_one(assoc_name, opts = nil, &block)
53
- association(__method__, assoc_name, opts, &block)
57
+ def has_one(assoc_name, __opts = nil, &block)
58
+ association(__method__, assoc_name, __opts, &block)
54
59
  end
55
60
 
56
61
  contract(
@@ -58,8 +63,8 @@ module ReeDao
58
63
  Nilor[Proc, Sequel::Dataset],
59
64
  Optblock => Any
60
65
  )
61
- def has_many(assoc_name, opts = nil, &block)
62
- association(__method__, assoc_name, opts, &block)
66
+ def has_many(assoc_name, __opts = nil, &block)
67
+ association(__method__, assoc_name, __opts, &block)
63
68
  end
64
69
 
65
70
  contract(Symbol, Proc => Any)
@@ -80,16 +85,16 @@ module ReeDao
80
85
  Nilor[Proc, Sequel::Dataset],
81
86
  Optblock => Any
82
87
  )
83
- def association(assoc_type, assoc_name, opts, &block)
88
+ def association(assoc_type, assoc_name, __opts, &block)
84
89
  if self.class.sync_mode?
85
90
  return if association_is_not_included?(assoc_name) || list.empty?
86
91
 
87
92
  association = Association.new(self, parent_dao_name, list, **global_opts)
88
93
 
89
94
  if assoc_type == :field
90
- association.handle_field(assoc_name, opts)
95
+ association.handle_field(assoc_name, __opts)
91
96
  else
92
- association.load(assoc_type, assoc_name, **get_assoc_opts(opts), &block)
97
+ association.load(assoc_type, assoc_name, **get_assoc_opts(__opts), &block)
93
98
  end
94
99
  else
95
100
  if association_is_not_included?(assoc_name) || list.empty?
@@ -99,7 +104,7 @@ module ReeDao
99
104
  association = Association.new(self, parent_dao_name, list, **global_opts)
100
105
 
101
106
  if assoc_type == :field
102
- field_proc = opts
107
+ field_proc = __opts
103
108
  {
104
109
  association_threads: @assoc_threads,
105
110
  field_threads: @field_threads << [
@@ -109,7 +114,7 @@ module ReeDao
109
114
  else
110
115
  {
111
116
  association_threads: @assoc_threads << [
112
- association, assoc_type, assoc_name, get_assoc_opts(opts), block
117
+ association, assoc_type, assoc_name, get_assoc_opts(__opts), block
113
118
  ],
114
119
  field_threads: @field_threads
115
120
  }
@@ -125,7 +130,10 @@ module ReeDao
125
130
  return false if only && only.include?(assoc_name)
126
131
 
127
132
  if only && !only.include?(assoc_name)
128
- return false if autoload_children
133
+ if autoload_children
134
+ return true if except && except.include?(assoc_name)
135
+ return false
136
+ end
129
137
  return true
130
138
  end
131
139
  end
@@ -105,7 +105,7 @@ RSpec.describe :load_agg do
105
105
  has_one :author
106
106
  has_many :chapters
107
107
 
108
- has_many :reviews do |reviews_list|
108
+ has_many :reviews, -> { reviews_opts } do |reviews_list|
109
109
  has_one :review_author
110
110
 
111
111
  field :review_calculatetable_field, -> { some_method(reviews_list) }
@@ -146,6 +146,10 @@ RSpec.describe :load_agg do
146
146
  scope: books.where(title: "1984")
147
147
  }
148
148
  end
149
+
150
+ def reviews_opts
151
+ { autoload_children: true }
152
+ end
149
153
  end
150
154
 
151
155
  class ReeDaoLoadAggTest::UsersAggWithDto
@@ -353,6 +357,24 @@ RSpec.describe :load_agg do
353
357
  end
354
358
  end
355
359
 
360
+ class ReeDaoLoadAggTest::UsersAggOnlyExceptKeys
361
+ include ReeDao::AggregateDSL
362
+
363
+ aggregate :users_agg_only_except_keys do
364
+ link :users, from: :ree_dao_load_agg_test
365
+ link :organizations, from: :ree_dao_load_agg_test
366
+ link :books, from: :ree_dao_load_agg_test
367
+ link :load_agg, from: :ree_dao
368
+ end
369
+
370
+ def call(ids_or_scope, **opts)
371
+ load_agg(users, ids_or_scope, **opts) do
372
+ belongs_to :organization
373
+ has_many :books
374
+ end
375
+ end
376
+ end
377
+
356
378
  let(:users_agg) { ReeDaoLoadAggTest::UsersAgg.new }
357
379
  let(:users_agg_block) { ReeDaoLoadAggTest::UsersAggBlockTest.new }
358
380
  let(:users_agg_scope_method) { ReeDaoLoadAggTest::UsersAggScopeMethodTest.new }
@@ -361,6 +383,7 @@ RSpec.describe :load_agg do
361
383
  let(:users_agg_without_dao) { ReeDaoLoadAggTest::UsersAggWithoutDao.new }
362
384
  let(:users_agg_with_dto) { ReeDaoLoadAggTest::UsersAggWithDto.new }
363
385
  let(:users_agg_only_dataset) { ReeDaoLoadAggTest::UsersAggOnlyDataset.new }
386
+ let(:user_agg_only_except_keys) { ReeDaoLoadAggTest::UsersAggOnlyExceptCase.new }
364
387
  let(:organizations) { ReeDaoLoadAggTest::Organizations.new }
365
388
  let(:users) { ReeDaoLoadAggTest::Users.new }
366
389
  let(:user_passports) { ReeDaoLoadAggTest::UserPassports.new }
@@ -385,6 +408,69 @@ RSpec.describe :load_agg do
385
408
  }.to raise_error(ArgumentError)
386
409
  }
387
410
 
411
+ it {
412
+ organizations.delete_all
413
+ users.delete_all
414
+ user_passports.delete_all
415
+ books.delete_all
416
+ chapters.delete_all
417
+
418
+ organization = ReeDaoLoadAggTest::Organization.new(name: "Test Org")
419
+ organizations.put(organization)
420
+
421
+ user_1 = ReeDaoLoadAggTest::User.new(name: "John", age: 33, organization_id: organization.id)
422
+ user_2 = ReeDaoLoadAggTest::User.new(name: "Sam", age: 21, organization_id: organization.id)
423
+ users.put(user_1)
424
+ users.put(user_2)
425
+
426
+ passport_1 = ReeDaoLoadAggTest::UserPassport.new(user_id: user_1.id, info: "some info")
427
+ user_passports.put(passport_1)
428
+ user_passports.put(ReeDaoLoadAggTest::UserPassport.new(user_id: user_2.id, info: "another info"))
429
+
430
+ book_1 = ReeDaoLoadAggTest::Book.new(user_id: user_1.id, title: "1984")
431
+ book_2 = ReeDaoLoadAggTest::Book.new(user_id: user_1.id, title: "1408")
432
+
433
+ books.put(book_1)
434
+ books.put(book_2)
435
+
436
+ chapter = ReeDaoLoadAggTest::Chapter.new(book_id: book_1.id, title: "beginning")
437
+ chapters.put(chapter)
438
+ chapters.put(ReeDaoLoadAggTest::Chapter.new(book_id: book_1.id, title: "interlude"))
439
+ chapters.put(ReeDaoLoadAggTest::Chapter.new(book_id: book_1.id, title: "tragic ending"))
440
+ chapters.put(ReeDaoLoadAggTest::Chapter.new(book_id: book_2.id, title: "beginning"))
441
+ chapters.put(ReeDaoLoadAggTest::Chapter.new(book_id: book_2.id, title: "ending"))
442
+
443
+
444
+ authors.put(ReeDaoLoadAggTest::Author.new(book_id: book_1.id, name: "George Orwell"))
445
+ review = ReeDaoLoadAggTest::Review.new(book_id: book_1.id, rating: 10)
446
+ reviews.put(review)
447
+ reviews.put(ReeDaoLoadAggTest::Review.new(book_id: book_1.id, rating: 7))
448
+ review_authors.put(ReeDaoLoadAggTest::ReviewAuthor.new(review_id: review.id, name: "John Review"))
449
+
450
+ res = users_agg.call(
451
+ users.all,
452
+ only: [:books, :reviews],
453
+ except: [:review_author]
454
+ )
455
+
456
+ expect(res.first.books.first.reviews.first.review_author).to eq(nil)
457
+ }
458
+
459
+ it {
460
+ organizations.delete_all
461
+ users.delete_all
462
+
463
+ organization = ReeDaoLoadAggTest::Organization.new(name: "Test Org")
464
+ organizations.put(organization)
465
+
466
+ user = ReeDaoLoadAggTest::User.new(name: "John", age: 33, organization_id: organization.id)
467
+ users.put(user)
468
+
469
+ expect {
470
+ users_agg_without_dao.call(users.all, only: [:books], except: [:books])
471
+ }.to raise_error(ArgumentError, "you can't use both :only and :except for \"books\" keys")
472
+ }
473
+
388
474
  it {
389
475
  organizations.delete_all
390
476
  users.delete_all
@@ -11,7 +11,7 @@ class ReeJson::Constants
11
11
  :object,
12
12
  :custom,
13
13
  :wab,
14
- ]
14
+ ].freeze
15
15
 
16
16
  ESCAPE_MODES = [
17
17
  :newline, # allows unescaped newlines in the output.
@@ -19,12 +19,13 @@ class ReeJson::Constants
19
19
  :xss_safe, # escapes HTML and XML characters such as & and <.
20
20
  :ascii, # escapes all non-ascii or characters with the hi-bit set.
21
21
  :unicode_xss, # escapes a special unicodes and is xss safe.
22
- ]
22
+ ].freeze
23
23
 
24
- TIME_FORMATS = []
24
+ TIME_FORMATS = [].freeze
25
25
 
26
26
  DEFAULT_OPTIONS = {
27
27
  time_format: :xmlschema,
28
- use_as_json: true
28
+ use_as_json: true,
29
+ mode: :rails,
29
30
  }.freeze
30
31
  end
@@ -3,7 +3,7 @@ class ReeJson::FromJson
3
3
 
4
4
  fn :from_json do
5
5
  link 'ree_json/constants', -> {
6
- DEFAULT_OPTIONS & MODES & ESCAPE_MODES & TIME_FORMATS
6
+ DEFAULT_OPTIONS & MODES & ESCAPE_MODES & TIME_FORMATS
7
7
  }
8
8
  end
9
9
 
@@ -11,23 +11,18 @@ class ReeJson::FromJson
11
11
 
12
12
  contract(
13
13
  Any,
14
- Kwargs[
15
- mode: Or[*MODES]
16
- ],
17
14
  Ksplat[
15
+ mode?: Or[*MODES],
18
16
  symbol_keys?: Bool,
19
17
  RestKeys => Any
20
- ] => Hash
18
+ ] => Any
21
19
  ).throws(ParseJsonError)
22
- def call(object, mode: :rails, **opts)
20
+ def call(object, **opts)
23
21
  options = DEFAULT_OPTIONS
24
- .dup
25
- .merge(
26
- opts.merge(mode: mode)
27
- )
22
+ .merge(opts)
28
23
 
29
24
  Oj.load(object, options)
30
- rescue ArgumentError, EncodingError
25
+ rescue ArgumentError, EncodingError, TypeError
31
26
  raise ParseJsonError.new
32
27
  end
33
28
  end
@@ -18,10 +18,8 @@ class ReeJson::ToJson
18
18
 
19
19
  contract(
20
20
  Any,
21
- Kwargs[
22
- mode: Or[*MODES]
23
- ],
24
21
  Ksplat[
22
+ mode?: Or[*MODES],
25
23
  escape_mode?: Or[*ESCAPE_MODES],
26
24
  float_precision?: Integer,
27
25
  time_format?: Or[*TIME_FORMATS],
@@ -31,13 +29,10 @@ class ReeJson::ToJson
31
29
  use_to_json?: Bool,
32
30
  RestKeys => Any
33
31
  ] => String
34
- ).throws(ArgumentError)
35
- def call(object, mode: :rails, **opts)
32
+ ).throws(ArgumentError, TypeError)
33
+ def call(object, **opts)
36
34
  options = DEFAULT_OPTIONS
37
- .dup
38
- .merge(
39
- opts.merge(mode: mode)
40
- )
35
+ .merge(opts)
41
36
 
42
37
  Oj.dump(object, options)
43
38
  end
@@ -12,22 +12,17 @@
12
12
  "throws": [
13
13
  "ReeJson::FromJson::ParseJsonError"
14
14
  ],
15
- "return": "Hash",
15
+ "return": "Any",
16
16
  "args": [
17
17
  {
18
18
  "arg": "object",
19
19
  "arg_type": "req",
20
20
  "type": "Any"
21
21
  },
22
- {
23
- "arg": "mode",
24
- "arg_type": "key",
25
- "type": "Or[strict, null, compat, json, rails, object, custom, wab]"
26
- },
27
22
  {
28
23
  "arg": "opts",
29
24
  "arg_type": "keyrest",
30
- "type": "Ksplat[:symbol_keys? => Bool, \"RestKeys\" => Any]"
25
+ "type": "Ksplat[:mode? => Or[strict, null, compat, json, rails, object, custom, wab], :symbol_keys? => Bool, \"RestKeys\" => Any]"
31
26
  }
32
27
  ]
33
28
  }
@@ -10,7 +10,8 @@
10
10
  {
11
11
  "doc": "Dumps arbitrary object to json using specific dump mode.\n to_json({id: 1}) # => \"{\"id\":1}\"\n to_json({id: 1}, mode: :object) # => \"{\":id\":{\"^o\":\"Object\"}}\"\n\nList of all available Ksplat options could be found here:\nhttps://github.com/ohler55/oj/blob/develop/pages/Modes.md",
12
12
  "throws": [
13
- "ArgumentError"
13
+ "ArgumentError",
14
+ "TypeError"
14
15
  ],
15
16
  "return": "String",
16
17
  "args": [
@@ -19,15 +20,10 @@
19
20
  "arg_type": "req",
20
21
  "type": "Any"
21
22
  },
22
- {
23
- "arg": "mode",
24
- "arg_type": "key",
25
- "type": "Or[strict, null, compat, json, rails, object, custom, wab]"
26
- },
27
23
  {
28
24
  "arg": "opts",
29
25
  "arg_type": "keyrest",
30
- "type": "Ksplat[:escape_mode? => Or[newline, json, xss_safe, ascii, unicode_xss...], :float_precision? => Integer, :time_format? => Or[], :use_as_json? => Bool, :use_raw_json? => Bool, :use_to_hash? => Bool, :use_to_json? => Bool, \"RestKeys\" => Any]"
26
+ "type": "Ksplat[:mode? => Or[strict, null, compat, json, rails, object, custom, wab], :escape_mode? => Or[newline, json, xss_safe, ascii, unicode_xss...], :float_precision? => Integer, :time_format? => Or[], :use_as_json? => Bool, :use_raw_json? => Bool, :use_to_hash? => Bool, :use_to_json? => Bool, \"RestKeys\" => Any]"
31
27
  }
32
28
  ]
33
29
  }
@@ -12,7 +12,39 @@ RSpec.describe :from_json do
12
12
  expect(result[:id]).to be_a(Object)
13
13
  }
14
14
 
15
+ it {
16
+ expect(from_json("null")).to eq(nil)
17
+ }
18
+
19
+ it {
20
+ expect(from_json("true")).to eq(true)
21
+ }
22
+
23
+ it {
24
+ expect(from_json('"hello"')).to eq("hello")
25
+ }
26
+
27
+ it {
28
+ expect(from_json("123")).to eq(123)
29
+ }
30
+
31
+ it {
32
+ expect(from_json("123.456")).to eq(123.456)
33
+ }
34
+
35
+ it {
36
+ expect(from_json("[1,true,\"hello\"]")).to eq([1, true, "hello"])
37
+ }
38
+
39
+ it {
40
+ expect(from_json("{\"^o\":\"Object\"}", mode: :object)).to be_a(Object)
41
+ }
42
+
15
43
  it {
16
44
  expect{from_json("{213: \"123\"}")}.to raise_error(ReeJson::FromJson::ParseJsonError)
17
45
  }
46
+
47
+ it {
48
+ expect { from_json(nil, mode: :strict) }.to raise_error(ReeJson::FromJson::ParseJsonError)
49
+ }
18
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReeLib
4
- VERSION = "1.0.64"
4
+ VERSION = "1.0.66"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.64
4
+ version: 1.0.66
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-01 00:00:00.000000000 Z
11
+ date: 2023-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ree