attributor 7.1 → 8.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: 6207241fe519ee3ee26e4a4220077428c26850c556abd065d7c073125c0a49fa
4
- data.tar.gz: bb19a849faf087d1f9fad40c9b3101b4a416ef32ef8f4d266b6a061c37f270e2
3
+ metadata.gz: 1bec1eaa11a8711121f24b64eb86dcedc3779012f3ccc2239882bfa38527a0db
4
+ data.tar.gz: 15e6274f319f78d5c7801015ed5a97fd3858727ce98956a2e3b0229c89bdf25c
5
5
  SHA512:
6
- metadata.gz: 5bbec43bae528b47ddc5176e75bbd07f84707520a363e08257dff88409d1a7b1f9febce1a77e2a99e4df07537d0ed6253d4e6911e453a51f28bcb3f7d445b6ff
7
- data.tar.gz: 12726d8e722d4ddc28c04bb6d03d3fae81b5f4abe84268f1e335f80a6e84880dcddc96ca12a9d1281abf4fac31c900d644c2f3e1ef9e1ff0d1929aeae0afe325
6
+ metadata.gz: 1055363cc837a07b3c319f0cfec62293797361a713354c146e3c1bead0b2fa0cbb2313dfcf092400abc57f5101a6fc76b782ba51bb9876c09720c2a382bb09de
7
+ data.tar.gz: 0aea79491d61b6ab866aec643c93d18bd372b8afc63428ba69d4a9723d0fd55a24589ea182a4ed2a0029e30a55f522981010f5637a54ea98af68ec0f41b48ec7
data/.travis.yml CHANGED
@@ -1,10 +1,8 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4
5
- - 2.5
6
- - 2.6
7
4
  - 2.7
5
+ - 3.2
8
6
  script:
9
7
  - bundle exec rspec spec
10
8
  branches:
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Attributor Changelog
2
2
 
3
- ## next
3
+ ## 8.0
4
+
5
+ - Add support for Ruby 3.2.
6
+ - Remove usage of Randexp for examples and replace with Faker.
7
+ - The above means this also removes support for generating examples using regular expressions.
4
8
 
5
9
  ## 7.1 (6/9/2023)
6
10
  - Enhance custom_option handling. The values provided for custom options are now loaded (and definition will fail if they aren't compatible). This was specially
@@ -37,7 +41,7 @@
37
41
  - added support for enum's out of values in json_schema generation
38
42
 
39
43
  ## 6.0 (22/11/2021)
40
- - removed `required_if` support and all of the necessary code.
44
+ - removed `required_if` support and all of the necessary code.
41
45
  - changed the semantics of the `required:` option in attributes, to really mean if the "key" is required to be passed in or not (i.e., check if the key is null, not if its value is null)
42
46
  - Introduced a new option`null: true|false` to allow for the value of an attribute to be nullable or not when the attribute is passed in.
43
47
  * The default behavior for an attribute nullability currently `null: false` (but it can be easily changed by overriding the `Attributor::Attribute.default_for_null` function to return `true`)
data/attributor.gemspec CHANGED
@@ -13,14 +13,14 @@ Gem::Specification.new do |spec|
13
13
 
14
14
  spec.homepage = 'https://github.com/rightscale/attributor'
15
15
  spec.license = 'MIT'
16
- spec.required_ruby_version = '>=2.1'
16
+ spec.required_ruby_version = '>=2.7'
17
17
 
18
18
  spec.require_paths = ['lib']
19
19
  spec.files = `git ls-files -z`.split("\x0")
20
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
21
 
22
22
  spec.add_runtime_dependency('hashie', ['~> 3'])
23
- spec.add_runtime_dependency('randexp', ['~> 0'])
23
+ spec.add_runtime_dependency('faker', [' >= 3.2'])
24
24
  spec.add_runtime_dependency('activesupport', ['>= 3'])
25
25
 
26
26
  spec.add_development_dependency 'rspec', '~> 3'
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency('guard', ['~> 2'])
35
35
  spec.add_development_dependency('guard-rspec', ['~> 4'])
36
36
  spec.add_development_dependency('pry')
37
+
37
38
  if RUBY_PLATFORM !~ /java/
38
39
  spec.add_development_dependency('pry-byebug')
39
40
  spec.add_development_dependency('pry-stack_explorer')
@@ -27,7 +27,7 @@ module Attributor
27
27
 
28
28
  class << self
29
29
  attr_accessor :custom_options
30
- end
30
+ end
31
31
 
32
32
  def self.custom_option(name, attr_type, options = {}, &block)
33
33
  if TOP_LEVEL_OPTIONS.include?(name) || INTERNAL_OPTIONS.include?(name)
@@ -47,7 +47,7 @@ module Attributor
47
47
  current_option_name = nil # Use this to avoid having to wrap each loop with a begin/rescue block
48
48
  (self.class.custom_options.keys & @options.keys).each do |custom_key|
49
49
  current_option_name = custom_key
50
- @options[custom_key] = self.class.custom_options[custom_key].load(@options[custom_key])
50
+ @options[custom_key] = self.class.custom_options[custom_key].load(@options[custom_key])
51
51
  end
52
52
  rescue => e
53
53
  raise AttributorException, "Error while loading value #{@options[current_option_name]} for custom option '#{current_option_name}': #{e.message}"
@@ -156,8 +156,6 @@ module Attributor
156
156
  def example_from_options(parent, context)
157
157
  val = options[:example]
158
158
  generated = case val
159
- when ::Regexp
160
- val.gen
161
159
  when ::Proc
162
160
  if val.arity == 2
163
161
  val.call(parent, context)
@@ -211,8 +209,10 @@ module Attributor
211
209
  description
212
210
  end
213
211
 
214
- def example(context=nil, parent: nil, values:{})
215
- raise ArgumentError, "attribute example cannot take a context of type String" if (context.is_a? ::String )
212
+ def example(context = nil, parent: nil, values: {})
213
+ require 'faker'
214
+ raise ArgumentError, 'attribute example cannot take a context of type String' if context.is_a? ::String
215
+
216
216
  if context
217
217
  ctx = Attributor.humanize_context(context)
218
218
  seed, = Digest::SHA1.digest(ctx).unpack('QQ')
@@ -226,10 +226,11 @@ module Attributor
226
226
  # Only validate the type, if the proc-generated example is "complex" (has attributes)
227
227
  errors = loaded.class.respond_to?(:attributes) ? validate_type(loaded, context) : validate(loaded, context)
228
228
  raise AttributorException, "Error generating example for #{Attributor.humanize_context(context)}. Errors: #{errors.inspect}" if errors.any?
229
+
229
230
  return loaded
230
231
  end
231
232
 
232
- return options[:values].pick if options.key? :values
233
+ return options[:values].sample if options.key? :values
233
234
 
234
235
  if type.respond_to?(:attributes)
235
236
  type.example(context, **values)
@@ -242,7 +243,7 @@ module Attributor
242
243
  type.attributes if @type_has_attributes ||= type.respond_to?(:attributes)
243
244
  end
244
245
 
245
- # Default value for a non-specified null: option
246
+ # Default value for a non-specified null: option
246
247
  def self.default_for_null
247
248
  false
248
249
  end
@@ -272,7 +273,7 @@ module Attributor
272
273
  end
273
274
 
274
275
  return errors if errors.any?
275
-
276
+
276
277
  object.nil? ? errors : errors + type.validate(object, context, self)
277
278
  end
278
279
 
@@ -303,7 +304,7 @@ module Attributor
303
304
  raise AttributorException, 'Required must be a boolean' unless definition == true || definition == false
304
305
  raise AttributorException, 'Required cannot be enabled in combination with :default' if definition == true && options.key?(:default)
305
306
  when :null
306
- raise AttributorException, 'Null must be a boolean' unless definition == true || definition == false
307
+ raise AttributorException, 'Null must be a boolean' unless definition == true || definition == false
307
308
  when :example
308
309
  unless definition.is_a?(::Regexp) || definition.is_a?(::String) || definition.is_a?(::Array) || definition.is_a?(::Proc) || definition.nil? || type.valid_type?(definition)
309
310
  raise AttributorException, "Invalid example type (got: #{definition.class.name}). It must always match the type of the attribute (except if passing Regex that is allowed for some types)"
@@ -317,8 +318,8 @@ module Attributor
317
318
  :ok # passes
318
319
  end
319
320
 
320
- def check_custom_option(name, definition)
321
- attribute = self.class.custom_options.fetch(name)
321
+ def check_custom_option(name, definition)
322
+ attribute = self.class.custom_options.fetch(name)
322
323
 
323
324
  errors = attribute.validate(definition)
324
325
  raise AttributorException, "Custom option #{name.inspect} is invalid: #{errors.inspect}" if errors.any?
@@ -22,7 +22,7 @@ module Attributor
22
22
 
23
23
  def self.example(_context = nil, options: {})
24
24
  3.times.each_with_object([]) do |_i, array|
25
- array << /\w{5,8}/.gen
25
+ array << Faker::Lordem.words(5)
26
26
  end.join(',')
27
27
  end
28
28
 
@@ -9,7 +9,7 @@ module Attributor
9
9
  end
10
10
 
11
11
  def self.example(_context = nil, options: {})
12
- BigDecimal("#{/\d{3}/.gen}.#{/\d{3}/.gen}")
12
+ BigDecimal("#{Faker::Number.decimal(l_digits: 3, r_digits: 3)}")
13
13
  end
14
14
 
15
15
  def self.load(value, _context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
@@ -9,7 +9,7 @@ module Attributor
9
9
  end
10
10
 
11
11
  def self.example(context = nil, options: {})
12
- load(Randgen.date, context)
12
+ load(Faker::Date.in_date_period, context)
13
13
  end
14
14
 
15
15
  def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
@@ -21,7 +21,7 @@ module Attributor
21
21
  case value
22
22
  when ::String
23
23
  begin
24
- return ::Date.parse(value)
24
+ ::Date.parse(value)
25
25
  rescue ArgumentError
26
26
  raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'Date', value: value)
27
27
  end
@@ -13,7 +13,7 @@ module Attributor
13
13
  end
14
14
 
15
15
  def self.example(context = nil, options: {})
16
- load(Randgen.date, context)
16
+ load(Faker::Date.in_date_period, context)
17
17
  end
18
18
 
19
19
  def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
@@ -21,10 +21,11 @@ module Attributor
21
21
  return value if value.is_a?(native_type)
22
22
  return value.to_datetime if value.respond_to?(:to_datetime)
23
23
  return nil unless value.is_a?(::String)
24
+
24
25
  # TODO: we should be able to convert not only from String but Time...etc
25
26
  # Else, we'll decode it from String.
26
27
  begin
27
- return ::DateTime.parse(value)
28
+ ::DateTime.parse(value)
28
29
  rescue ArgumentError
29
30
  raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'DateTime', value: value)
30
31
  end
@@ -27,7 +27,7 @@ module Attributor
27
27
  end
28
28
 
29
29
  def self.example(context = nil, **values)
30
- types.values.pick.example(context, **values)
30
+ types.values.sample.example(context, **values)
31
31
  end
32
32
 
33
33
  def self.valid_type?(value)
@@ -17,16 +17,7 @@ module Attributor
17
17
  end
18
18
 
19
19
  def self.example(_context = nil, options: {})
20
- if options[:regexp]
21
- begin
22
- # It may fail to generate an example, see bug #72.
23
- options[:regexp].gen
24
- rescue => e
25
- format('Failed to generate example for %s : %s', options[:regexp].inspect, e.message)
26
- end
27
- else
28
- /\w+/.gen
29
- end
20
+ Faker::Lorem.word
30
21
  end
31
22
 
32
23
  def self.family
@@ -10,7 +10,7 @@ module Attributor
10
10
 
11
11
  def self.example(context = Attributor::DEFAULT_ROOT_CONTEXT, options: {})
12
12
  file = ::Tempfile.new(Attributor.humanize_context(context))
13
- file.write Randgen.sentence
13
+ file.write Faker::Lorem.paragraph
14
14
  file.write '.'
15
15
  file.rewind
16
16
  file
@@ -9,7 +9,7 @@ module Attributor
9
9
  end
10
10
 
11
11
  def self.example(context = nil, options: {})
12
- load(Randgen.time, context)
12
+ load(Faker::Time.between(from: ::DateTime.now - 1, to: ::DateTime.now), context)
13
13
  end
14
14
 
15
15
  def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
@@ -24,10 +24,10 @@ module Attributor
24
24
  def self.parse(value, context)
25
25
  case value
26
26
  when ::Integer
27
- return ::Time.at(value)
27
+ ::Time.at(value)
28
28
  when ::String
29
29
  begin
30
- return ::Time.parse(value)
30
+ ::Time.parse(value)
31
31
  rescue ArgumentError
32
32
  raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'Time', value: value)
33
33
  end
@@ -31,7 +31,7 @@ module Attributor
31
31
  end
32
32
 
33
33
  def self.example(_context = nil, options: {})
34
- URI(Randgen.uri)
34
+ URI("https://example.com/#{Attributor::String.example}")
35
35
  end
36
36
 
37
37
  def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
@@ -1,3 +1,3 @@
1
1
  module Attributor
2
- VERSION = '7.1'.freeze
2
+ VERSION = '8.0'.freeze
3
3
  end
data/lib/attributor.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'json'
2
- require 'randexp'
3
2
 
4
3
  require 'hashie'
5
4
  require 'active_support/concern'
@@ -17,8 +16,6 @@ module Attributor
17
16
 
18
17
  require_relative 'attributor/example_mixin'
19
18
 
20
- require_relative 'attributor/extensions/randexp'
21
-
22
19
  # hierarchical separator string for composing human readable attributes
23
20
  SEPARATOR = '.'.freeze
24
21
  ROOT_PREFIX = '$'.freeze
@@ -37,11 +34,13 @@ module Attributor
37
34
 
38
35
  def self.find_type(attr_type)
39
36
  return attr_type if attr_type < Attributor::Type
37
+
40
38
  name = attr_type.name.split('::').last # TOO EXPENSIVE?
41
39
 
42
40
  klass = const_get(name) if const_defined?(name)
43
41
  raise AttributorException, "Could not find class with name #{name}" unless klass
44
42
  raise AttributorException, "Could not find attribute type for: #{name} [klass: #{klass.name}]" unless klass < Attributor::Type
43
+
45
44
  klass
46
45
  end
47
46
 
@@ -57,7 +56,7 @@ module Attributor
57
56
  context = Array(context) if context.is_a? ::String
58
57
 
59
58
  begin
60
- return context.join('.')
59
+ context.join('.')
61
60
  rescue e
62
61
  raise "Error creating context string: #{e.message}"
63
62
  end
@@ -81,7 +80,7 @@ module Attributor
81
80
  else
82
81
  val
83
82
  end
84
- end
83
+ end
85
84
 
86
85
  MODULE_PREFIX = 'Attributor::'.freeze
87
86
  MODULE_PREFIX_REGEX = ::Regexp.new(MODULE_PREFIX)
@@ -273,7 +273,7 @@ describe Attributor::Attribute do
273
273
  end
274
274
 
275
275
  context 'deterministic examples' do
276
- let(:example) { /\w+/ }
276
+ let(:example) { proc { Faker::Lorem.word } }
277
277
  let(:attribute_options) { { example: example } }
278
278
 
279
279
  it 'can take a context to pre-seed the random number generator' do
@@ -332,30 +332,6 @@ describe Attributor::Attribute do
332
332
  it { should be example }
333
333
  end
334
334
 
335
- context 'with a regexp' do
336
- let(:example) { Regexp.new(/\w+/) }
337
- let(:generated_example) { /\w+/.gen }
338
-
339
- it 'calls #gen on the regexp' do
340
- expect(example).to receive(:gen).and_return(generated_example)
341
-
342
- expect(example_result).to match example
343
- end
344
-
345
- context 'for a type with a non-String native_type' do
346
- let(:type) { Attributor::Integer }
347
- let(:example) { Regexp.new(/\d{5}/) }
348
- let(:generated_example) { /\d{5}/.gen }
349
-
350
- it 'coerces the example value properly' do
351
- expect(example).to receive(:gen).and_return(generated_example)
352
- expect(type).to receive(:load).and_call_original
353
-
354
- expect(example_result).to be_kind_of(type.native_type)
355
- end
356
- end
357
- end
358
-
359
335
  context 'with a proc' do
360
336
  let(:parent) { Object.new }
361
337
 
@@ -1,6 +1,6 @@
1
1
  class HashWithModel < Attributor::Hash
2
2
  keys do
3
- key :name, String, default: 'Turkey McDucken', description: 'Turducken name', example: Randgen.name
3
+ key :name, String, default: 'Turkey McDucken', description: 'Turducken name', example: proc { Faker::Name.first_name }
4
4
  key :chicken, Chicken
5
5
  end
6
6
  end
@@ -1,10 +1,10 @@
1
1
  class Chicken < Attributor::Model
2
2
  attributes(identity: :email) do
3
- attribute :name, Attributor::String, example: Randgen.first_name
3
+ attribute :name, Attributor::String, example: proc { Faker::Name.first_name }
4
4
  attribute :age, Attributor::Integer, default: 1, min: 0, max: 120, description: 'The age of the chicken'
5
- attribute :email, Attributor::String, example: Randgen.email, regexp: /@/, description: 'The email address of the chicken'
5
+ attribute :email, Attributor::String, example: proc { "#{Faker::Name.first_name.downcase}@#{Faker::Lorem.word.downcase}.example.org" }, regexp: /@/, description: 'The email address of the chicken'
6
6
  attribute :angry, Attributor::Boolean, example: 'true', description: 'Angry bird?'
7
- attribute :weight, Attributor::Float, example: /\d{1,2}\.\d/, description: 'The weight of the chicken'
7
+ attribute :weight, Attributor::Float, example: proc { Faker::Number.number(digits: 3) }, description: 'The weight of the chicken'
8
8
  attribute :type, Attributor::Symbol, values: [:chicken]
9
9
  end
10
10
  end
@@ -14,8 +14,8 @@ class Duck < Attributor::Model
14
14
  attribute :age, Attributor::Integer
15
15
  attribute :name, Attributor::String
16
16
  attribute :email, Attributor::String
17
- attribute :angry, Attributor::Boolean, default: true, example: /true|false/, description: 'Angry bird?'
18
- attribute :weight, Attributor::Float, example: /\d{1,2}\.\d/, description: 'The weight of the duck'
17
+ attribute :angry, Attributor::Boolean, default: true, example: proc { [true, false].sample }, description: 'Angry bird?'
18
+ attribute :weight, Attributor::Float, example: proc { Faker::Number.number(digits: 3).to_f }, description: 'The weight of the duck'
19
19
  attribute :type, Attributor::Symbol, values: [:duck]
20
20
  end
21
21
  end
@@ -23,16 +23,16 @@ end
23
23
  class Turkey < Attributor::Model
24
24
  attributes do
25
25
  attribute :age, Integer, default: 1, min: 0, max: 120, description: 'The age of the turkey'
26
- attribute :name, String, description: 'name of the turkey', example: Randgen.name # , :default => "Providencia Zboncak"
27
- attribute :email, String, example: Randgen.email, regexp: /@/, description: 'The email address of the turkey'
28
- attribute :weight, Attributor::Float, example: /\d{1,2}\.\d/, max: 100.0, description: 'The weight of the turkey'
26
+ attribute :name, String, description: 'name of the turkey', example: proc { Faker::Name.name } # , :default => "Providencia Zboncak"
27
+ attribute :email, String, example: proc { "#{Faker::Name.first_name.downcase}@example.org" }, regexp: /@/, description: 'The email address of the turkey'
28
+ attribute :weight, Attributor::Float, example: proc { Faker::Number.number(digits: 2).to_f }, max: 100.0, description: 'The weight of the turkey'
29
29
  attribute :type, Attributor::Symbol, values: [:turkey]
30
30
  end
31
31
  end
32
32
 
33
33
  class Turducken < Attributor::Model
34
34
  attributes do
35
- attribute :name, String, default: 'Turkey McDucken', description: 'Turducken name', example: Randgen.name
35
+ attribute :name, String, default: 'Turkey McDucken', description: 'Turducken name', example: proc { Faker::Name.first_name }
36
36
  attribute :chicken, Chicken
37
37
  attribute :duck, Duck
38
38
  attribute :turkey, Turkey, description: 'The turkey'
@@ -43,7 +43,7 @@ end
43
43
 
44
44
  class Cormorant < Attributor::Model
45
45
  attributes do
46
- attribute :name, String, description: 'Name of the Cormorant', example: Randgen.name
46
+ attribute :name, String, description: 'Name of the Cormorant', example: proc { Faker::Name.name }
47
47
  attribute :timestamps do
48
48
  attribute :born_at, DateTime
49
49
  attribute :died_at, DateTime, example: proc { |timestamps| timestamps.born_at + 10 }
@@ -53,22 +53,22 @@ class Cormorant < Attributor::Model
53
53
  attribute :all_the_fish, Attributor::Collection, description: 'All kinds of fish for feeding the babies'
54
54
 
55
55
  # This will be a collection of Cormorants (note, this relationship is circular)
56
- attribute :neighbors, Attributor::Collection.of(Cormorant), member_options: {null: false}, description: 'Neighbor cormorants', null: false
56
+ attribute :neighbors, Attributor::Collection.of(Cormorant), member_options: { null: false }, description: 'Neighbor cormorants', null: false
57
57
 
58
58
  # This will be a collection of instances of an anonymous Struct class, each having two well-defined attributes
59
59
 
60
60
  attribute :babies, Attributor::Collection.of(Attributor::Struct), description: 'All the babies', member_options: { identity: :name } do
61
- attribute :name, Attributor::String, example: /[:name]/, description: 'The name of the baby cormorant', required: true
61
+ attribute :name, Attributor::String, example: proc { Faker::Name.name }, description: 'The name of the baby cormorant', required: true
62
62
  attribute :months, Attributor::Integer, default: 0, min: 0, description: 'The age in months of the baby cormorant'
63
- attribute :weight, Attributor::Float, example: /\d{1,2}\.\d{3}/, description: 'The weight in kg of the baby cormorant'
63
+ attribute :weight, Attributor::Float, example: proc { Faker::Number.number(digits: 2) }, description: 'The weight in kg of the baby cormorant'
64
64
  end
65
65
  end
66
66
  end
67
67
 
68
68
  class Person < Attributor::Model
69
69
  attributes do
70
- attribute :name, String, example: Randgen.first_name
71
- attribute :title, String, values: %w(Mr Mrs Ms Dr)
70
+ attribute :name, String, example: proc { Faker::Name.first_name }
71
+ attribute :title, String, values: %w[Mr Mrs Ms Dr]
72
72
  attribute :okay, Attributor::Boolean, values: [true]
73
73
  attribute :address, Address, example: proc { |person, context| Address.example(context, person: person) }
74
74
  end
@@ -77,7 +77,7 @@ end
77
77
  class Address < Attributor::Model
78
78
  attributes do
79
79
  attribute :name, String, example: /\w+/, null: true
80
- attribute :state, String, values: %w(OR CA), null: false
80
+ attribute :state, String, values: %w[OR CA], null: false
81
81
  attribute :person, Person, example: proc { |address, context| Person.example(context, address: address) }
82
82
  attribute :substruct, reference: Address, null: false do
83
83
  attribute :state, Struct do # redefine state as a Struct
@@ -29,7 +29,7 @@ describe Attributor::CSV do
29
29
 
30
30
  context '.dump' do
31
31
  let!(:int_vals) { [1, 2, 3] }
32
- let!(:str_vals) { (0..2).collect { /\w+/.gen } }
32
+ let!(:str_vals) { (0..2).collect { Faker::Lorem.word } }
33
33
 
34
34
  it 'dumps a String value' do
35
35
  expect(csv.dump(int_vals)).to be_a(String)
@@ -19,7 +19,7 @@ describe Attributor::Date do
19
19
  let(:example) { type.example }
20
20
  subject(:value) { type.dump(example) }
21
21
  it 'is formatted correctly' do
22
- expect(value).to match(/\d{4}-\d{2}-\d{2}T00:00:00\+00:00/)
22
+ expect(value).to match(/\d{4}-\d{2}-\d{2}/)
23
23
  end
24
24
  context 'nil values' do
25
25
  it 'should be nil' do
@@ -59,7 +59,7 @@ describe Attributor::Date do
59
59
  'Sat, 3 Feb 2001 04:05:06 +0700',
60
60
  '2013/08/23 00:39:55 +0000',
61
61
  '2007-10-19T04:11:33Z',
62
- '2001-02-03T04:05:06+07:00.123456', # custom format with microseconds
62
+ '2001-02-03T04:05:06+07:00.123456' # custom format with microseconds
63
63
  ].each do |value|
64
64
  it "returns correct Date for #{value.inspect}" do
65
65
  expect(type.load(value)).to eq Date.parse(value)
@@ -70,7 +70,7 @@ describe Attributor::Date do
70
70
  'Sat, 30 Feb 2001 04:05:06 GMT', # No such date exists
71
71
  '2013/08/33 00:39:55 +0000',
72
72
  '2007-10-33T04:11:33Z',
73
- '2001-02-33T04:05:06+07:00.123456', # custom format with microseconds
73
+ '2001-02-33T04:05:06+07:00.123456' # custom format with microseconds
74
74
  ].each do |value|
75
75
  it "raises Attributor::AttributorException for #{value.inspect}" do
76
76
  expect do
@@ -82,7 +82,7 @@ describe Attributor::Date do
82
82
  [
83
83
  '',
84
84
  'foobar',
85
- 'Sat, 30 Feb 2001 04:05:06 FOOBAR', # No such date format exists
85
+ 'Sat, 30 Feb 2001 04:05:06 FOOBAR' # No such date format exists
86
86
  ].each do |value|
87
87
  it "raises Attributor::AttributorException for #{value.inspect}" do
88
88
  expect do
@@ -93,11 +93,11 @@ describe Attributor::Date do
93
93
  end
94
94
  end
95
95
  context '.as_json_schema' do
96
- subject(:js){ type.as_json_schema }
96
+ subject(:js) { type.as_json_schema }
97
97
  it 'adds the right attributes' do
98
98
  expect(js.keys).to include(:type, :'x-type_name')
99
99
  expect(js[:type]).to eq(:string)
100
- expect(js[:format]).to eq(:'date')
100
+ expect(js[:format]).to eq(:date)
101
101
  expect(js[:'x-type_name']).to eq('Date')
102
102
  end
103
103
  end
@@ -80,7 +80,7 @@ describe Attributor::Model do
80
80
  subject(:chicken) { Chicken.example }
81
81
 
82
82
  let(:age_opts) { { options: Chicken.attributes[:age].options } }
83
- let(:age) { /\d{2}/.gen.to_i }
83
+ let(:age) { Faker::Number.number(digits: 2) }
84
84
 
85
85
  context 'for a simple model' do
86
86
  it { should be_kind_of(Chicken) }
@@ -22,14 +22,6 @@ describe Attributor::String do
22
22
  expect(type.example).to be_a(::String)
23
23
  end
24
24
 
25
- it 'handles regexps that Randexp can not (#72)' do
26
- regex = /\w+(,\w+)*/
27
- expect do
28
- val = Attributor::String.example(options: { regexp: regex })
29
- expect(val).to be_a(::String)
30
- expect(val).to match(/Failed to generate.+is too vague/)
31
- end.to_not raise_error
32
- end
33
25
  end
34
26
 
35
27
  context '.load' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attributor
3
3
  version: !ruby/object:Gem::Version
4
- version: '7.1'
4
+ version: '8.0'
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: 2023-06-09 00:00:00.000000000 Z
12
+ date: 2023-08-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: hashie
@@ -26,19 +26,19 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  version: '3'
28
28
  - !ruby/object:Gem::Dependency
29
- name: randexp
29
+ name: faker
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
34
+ version: '3.2'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
41
+ version: '3.2'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: activesupport
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -316,7 +316,6 @@ files:
316
316
  - lib/attributor/dumpable.rb
317
317
  - lib/attributor/example_mixin.rb
318
318
  - lib/attributor/exceptions.rb
319
- - lib/attributor/extensions/randexp.rb
320
319
  - lib/attributor/extras/field_selector.rb
321
320
  - lib/attributor/extras/field_selector/parser.rb
322
321
  - lib/attributor/extras/field_selector/transformer.rb
@@ -400,14 +399,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
400
399
  requirements:
401
400
  - - ">="
402
401
  - !ruby/object:Gem::Version
403
- version: '2.1'
402
+ version: '2.7'
404
403
  required_rubygems_version: !ruby/object:Gem::Requirement
405
404
  requirements:
406
405
  - - ">="
407
406
  - !ruby/object:Gem::Version
408
407
  version: '0'
409
408
  requirements: []
410
- rubygems_version: 3.3.7
409
+ rubygems_version: 3.4.10
411
410
  signing_key:
412
411
  specification_version: 4
413
412
  summary: A powerful attribute and type management library for Ruby
@@ -1,13 +0,0 @@
1
- require 'date'
2
-
3
- class Randgen
4
- DATE_TIME_EPOCH = ::DateTime.new(2015, 1, 1, 0, 0, 0)
5
-
6
- def self.date
7
- DATE_TIME_EPOCH - rand(800)
8
- end
9
-
10
- def self.time
11
- date.to_time
12
- end
13
- end