praxis 2.0.pre.23 → 2.0.pre.24

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: 222cfa107a8b45e1a7d397af277fc07448daa18849e13b5c115565d0e7db4996
4
- data.tar.gz: 5fabb6000f848c062e813def28902ca002a33537ffe71a480daa7b84506a62b8
3
+ metadata.gz: 7f399850436ae7099b3d2bcef4f1d0648b094af1d307f47498d92c3ce275379a
4
+ data.tar.gz: 5f1fa0dbad1f3cf54de9c1a398f93f72c994fe7e61e081ab0e4af3e90f1941b0
5
5
  SHA512:
6
- metadata.gz: d0221bd47825ca1a92828c819cb2016bcbecdcff3c7546a8ee8160ac71fce38d7f17e442bec31c9ffeae3d4af74a794cad056ff348709c60cf226f56d31e76bb
7
- data.tar.gz: e1635b5788fbed05bbd8daa8198a75bcb6aa40aedef9e1a89504f874ba7f306e70876e8fc0fed7a5ca90c5111a1c8846b1fd0f414bc85909835038cd6a46feef
6
+ metadata.gz: a1bb3ad07b0376ea46601104c0c5539cf39c4027e787f5228366cc5d5d7ff2a0ec44b8bf516ae3692ddd4ce781e4695faf760cb46750ad052e66f0618b454b71
7
+ data.tar.gz: 0d9689af7ec169f05a39113c69deb470f70cb41425b0aca71102fd7bb32f877fb8dfca73737ec6935b3b6afcf43e79d670881344c56cffdf13ee9162126c2a05
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## next
4
4
 
5
+ ## 2.0.pre.24
6
+ Assorted set of fixes and cleanup:
7
+ * better forwarding signature for query methods
8
+ * Fix the way with which to decide how to wrap an association (based on Enumerable isn't right, as Hashes are Enumerable as well). Wrapping decision
9
+ is now made based on the association type, and not the shape of the resulting type.
10
+ * Built handling of some multivalue and/or fuzzy matching cases in filtering params
11
+ * unrestrict mustermann's dependent version
12
+ * Support options and even passing a full type (instead of a block) in signature definitions (TypedMethods for resources)
13
+
5
14
  ## 2.0.pre.22
6
15
  * Small fix in OpenAPI doc generation, which would detect and report more output types, even if they are only defined within the
7
16
  children of anonymous types.
@@ -250,7 +250,8 @@ module Praxis
250
250
  next unless item[:value].presence
251
251
 
252
252
  fuzzy_match = attr_filters[:fuzzy_match]
253
- errors << "Fuzzy matching for #{attr_name} is not allowed (yet '*' was found in the value)" if item[:fuzzy] && !item[:fuzzy].empty? && !fuzzy_match
253
+ # If fuzzy matches aren't allowed, but there is one passed in (or in the case of a multimatch, any of the ones in it), we disallow it
254
+ errors << "Fuzzy matching for #{attr_name} is not allowed (yet '*' was found in the value)" if item[:fuzzy] && !fuzzy_match && !(item[:fuzzy].is_a?(Array) && item[:fuzzy].compact.empty?)
254
255
  end
255
256
  end
256
257
 
@@ -258,7 +259,29 @@ module Praxis
258
259
  def dump
259
260
  parsed_array.each_with_object([]) do |item, arr|
260
261
  field = item[:name]
261
- arr << "#{field}#{item[:op]}#{item[:value]}"
262
+ value = \
263
+ if item[:value].is_a?(Array)
264
+ item[:value].map.with_index do |i, idx|
265
+ case item[:fuzzy][idx]
266
+ when nil
267
+ i
268
+ when :start
269
+ "*#{i}"
270
+ when :end
271
+ "#{i}*"
272
+ end
273
+ end.join(',')
274
+ else
275
+ case item[:fuzzy]
276
+ when nil
277
+ item[:value]
278
+ when :start
279
+ "*#{item[:value]}"
280
+ when :end
281
+ "#{item[:value]}*"
282
+ end
283
+ end
284
+ arr << "#{field}#{item[:op]}#{value}"
262
285
  end.join('&')
263
286
  end
264
287
 
@@ -177,13 +177,24 @@ module Praxis
177
177
  return unless association_resource_class
178
178
 
179
179
  memoized_variables << name
180
+
181
+ # Add the call to wrap (for true collections) or simply for_record if it's a n:1 association
182
+ wrapping = \
183
+ case association_spec.fetch(:type)
184
+ when :one_to_many, :many_to_many
185
+ "@__#{name} ||= #{association_resource_class}.wrap(records)"
186
+ else
187
+ "@__#{name} ||= #{association_resource_class}.for_record(records)"
188
+ end
189
+
180
190
  module_eval <<-RUBY, __FILE__, __LINE__ + 1
181
191
  def #{name}
182
192
  return @__#{name} if instance_variable_defined?("@__#{name}")
183
193
 
184
194
  records = record.#{name}
185
195
  return nil if records.nil?
186
- @__#{name} ||= #{association_resource_class}.wrap(records)
196
+
197
+ #{wrapping}
187
198
  end
188
199
  RUBY
189
200
  end
@@ -13,8 +13,8 @@ module Praxis
13
13
  QueryProxy.new(klass: self).including(args)
14
14
  end
15
15
 
16
- def all(args = {})
17
- QueryProxy.new(klass: self).all(args)
16
+ def all(...)
17
+ QueryProxy.new(klass: self).all(...)
18
18
  end
19
19
 
20
20
  def get(args)
@@ -22,7 +22,7 @@ module Praxis
22
22
  base = klass.model._add_includes(klass.model, @_includes) # includes(nil) seems to have no effect
23
23
  record = base._get(condition)
24
24
 
25
- record.nil? ? nil : klass.wrap(record)
25
+ record.nil? ? nil : klass.for_record(record)
26
26
  end
27
27
 
28
28
  def get!(condition)
@@ -40,17 +40,25 @@ module Praxis
40
40
  super
41
41
  end
42
42
 
43
- def signature(method_name, &block)
43
+ # It can take options to be passed to the attribute's block of the constructed struct
44
+ # It can take an already existing struct instead of a block/options
45
+ def signature(method_name, same_as_type = nil, **opts, &block)
44
46
  method = method_name.to_sym
45
47
  @signatures ||= {}
48
+ raise "signature definition for #{method_name}: need to pass either an existing type or a block, not both" if block_given? && same_as_type
49
+
46
50
  if block_given?
47
51
  type =
48
52
  Class.new(Attributor::Struct) do
49
- attributes do
53
+ attributes(**opts) do
50
54
  instance_eval(&block)
51
55
  end
52
56
  end
53
57
  @signatures[method] = type
58
+ elsif same_as_type
59
+ raise "Options for signature definition for #{method_name} are not supported when passing an already existing type" unless opts.empty?
60
+
61
+ @signatures[method] = same_as_type
54
62
  else
55
63
  @signatures[method]
56
64
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Praxis
4
- VERSION = '2.0.pre.23'
4
+ VERSION = '2.0.pre.24'
5
5
  end
data/praxis.gemspec CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency 'activesupport', '>= 3'
26
26
  spec.add_dependency 'attributor', '>= 6.2'
27
27
  spec.add_dependency 'mime', '~> 0'
28
- spec.add_dependency 'mustermann', '>=1.1', '<=2'
28
+ spec.add_dependency 'mustermann', '>=1.1'
29
29
  spec.add_dependency 'rack', '>= 1'
30
30
  spec.add_dependency 'terminal-table', '~> 1.4'
31
31
  spec.add_dependency 'thor'
@@ -278,12 +278,46 @@ describe Praxis::Extensions::AttributeFiltering::FilteringParams do
278
278
  expect(subject.first).to match(/Fuzzy matching for content is not allowed/)
279
279
  end
280
280
  end
281
+ context 'given a fuzzy string in only one of the values' do
282
+ let(:filters_string) { 'content=IAmNotFuzzy,IAmAString*' }
283
+ it 'errors out' do
284
+ expect(subject).to_not be_empty
285
+ expect(subject.first).to match(/Fuzzy matching for content is not allowed/)
286
+ end
287
+ end
281
288
  context 'given a non-fuzzy string' do
282
289
  let(:filters_string) { 'content=IAmAString' }
283
290
  it 'validates properly' do
284
291
  expect(subject).to be_empty
285
292
  end
286
293
  end
294
+ context 'given a non-fuzzy string for a multivalue' do
295
+ let(:filters_string) { 'content=IAmAString,IAmAnotherString' }
296
+ it 'validates properly' do
297
+ expect(subject).to be_empty
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+
304
+ context '.dump' do
305
+ context 'round trips for different types' do
306
+ it 'round trips for different types of values and operators' do
307
+ str = 'one=11&two!=22&three>=33&four<=4&five<5&six>6&seven!&eight!!'
308
+ expect(described_class.load(str).dump).to eq(str)
309
+ end
310
+ it 'round trips for multivalues' do
311
+ str = 'filtername=1,2,3'
312
+ expect(described_class.load(str).dump).to eq(str)
313
+ end
314
+ it 'round trips for fuzzies' do
315
+ str = 'filtername=file*'
316
+ expect(described_class.load(str).dump).to eq(str)
317
+ end
318
+ it 'round trips for fuzzies in multivalues' do
319
+ str = 'filtername=1,*2,3*'
320
+ expect(described_class.load(str).dump).to eq(str)
287
321
  end
288
322
  end
289
323
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: praxis
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.pre.23
4
+ version: 2.0.pre.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josep M. Blanquer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-07-13 00:00:00.000000000 Z
12
+ date: 2022-10-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -60,9 +60,6 @@ dependencies:
60
60
  - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '1.1'
63
- - - "<="
64
- - !ruby/object:Gem::Version
65
- version: '2'
66
63
  type: :runtime
67
64
  prerelease: false
68
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -70,9 +67,6 @@ dependencies:
70
67
  - - ">="
71
68
  - !ruby/object:Gem::Version
72
69
  version: '1.1'
73
- - - "<="
74
- - !ruby/object:Gem::Version
75
- version: '2'
76
70
  - !ruby/object:Gem::Dependency
77
71
  name: rack
78
72
  requirement: !ruby/object:Gem::Requirement