dirty_seed 0.1.7 → 0.1.8

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -2
  3. data/lib/dirty_seed.rb +15 -11
  4. data/lib/dirty_seed/assigners/assigner.rb +73 -0
  5. data/lib/dirty_seed/assigners/base.rb +86 -0
  6. data/lib/dirty_seed/assigners/{dirty_boolean.rb → boolean.rb} +2 -2
  7. data/lib/dirty_seed/assigners/{dirty_date.rb → date.rb} +2 -2
  8. data/lib/dirty_seed/assigners/fakers.yml +64 -1
  9. data/lib/dirty_seed/assigners/float.rb +21 -0
  10. data/lib/dirty_seed/assigners/integer.rb +20 -0
  11. data/lib/dirty_seed/assigners/min_max_helper.rb +115 -0
  12. data/lib/dirty_seed/assigners/{dirty_number.rb → number.rb} +2 -2
  13. data/lib/dirty_seed/assigners/string.rb +39 -0
  14. data/lib/dirty_seed/assigners/{dirty_time.rb → time.rb} +2 -2
  15. data/lib/dirty_seed/{dirty_association.rb → association.rb} +6 -17
  16. data/lib/dirty_seed/attribute.rb +62 -0
  17. data/lib/dirty_seed/data_model.rb +17 -18
  18. data/lib/dirty_seed/method_missing_helper.rb +1 -1
  19. data/lib/dirty_seed/{dirty_model.rb → model.rb} +81 -33
  20. data/lib/dirty_seed/version.rb +1 -1
  21. data/spec/dummy/app/models/bravo.rb +2 -1
  22. data/spec/dummy/db/test.sqlite3 +0 -0
  23. data/spec/dummy/log/development.log +2 -0
  24. data/spec/dummy/log/test.log +62192 -0
  25. data/spec/lib/dirty_seed/assigners/assigner_spec.rb +19 -0
  26. data/spec/lib/dirty_seed/assigners/base_spec.rb +81 -0
  27. data/spec/lib/dirty_seed/assigners/boolean_spec.rb +13 -0
  28. data/spec/lib/dirty_seed/assigners/date_spec.rb +15 -0
  29. data/spec/lib/dirty_seed/assigners/float_spec.rb +43 -0
  30. data/spec/lib/dirty_seed/assigners/integer_spec.rb +43 -0
  31. data/spec/lib/dirty_seed/assigners/string_spec.rb +47 -0
  32. data/spec/lib/dirty_seed/assigners/time_spec.rb +15 -0
  33. data/spec/lib/dirty_seed/association_spec.rb +64 -0
  34. data/spec/lib/dirty_seed/attribute_spec.rb +49 -0
  35. data/spec/lib/dirty_seed/data_model_spec.rb +8 -36
  36. data/spec/lib/dirty_seed/{dirty_model_spec.rb → model_spec.rb} +13 -13
  37. data/spec/support/helpers.rb +5 -5
  38. metadata +37 -33
  39. data/lib/dirty_seed/assigners/dirty_assigner.rb +0 -95
  40. data/lib/dirty_seed/assigners/dirty_float.rb +0 -35
  41. data/lib/dirty_seed/assigners/dirty_integer.rb +0 -16
  42. data/lib/dirty_seed/assigners/dirty_string.rb +0 -74
  43. data/lib/dirty_seed/dirty_attribute.rb +0 -75
  44. data/spec/lib/dirty_seed/assigners/dirty_assigner_spec.rb +0 -68
  45. data/spec/lib/dirty_seed/assigners/dirty_boolean_spec.rb +0 -13
  46. data/spec/lib/dirty_seed/assigners/dirty_date_spec.rb +0 -15
  47. data/spec/lib/dirty_seed/assigners/dirty_float_spec.rb +0 -43
  48. data/spec/lib/dirty_seed/assigners/dirty_integer_spec.rb +0 -43
  49. data/spec/lib/dirty_seed/assigners/dirty_string_spec.rb +0 -53
  50. data/spec/lib/dirty_seed/assigners/dirty_time_spec.rb +0 -15
  51. data/spec/lib/dirty_seed/dirty_association_spec.rb +0 -64
  52. data/spec/lib/dirty_seed/dirty_attribute_spec.rb +0 -49
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::Assigner do
6
+ describe 'uniqueness' do
7
+ context 'when value should be unique' do
8
+ it 'returns unique value or nil' do
9
+ attribute = build_attribute(type: :integer)
10
+ assigner = DirtySeed::Assigners::Integer.new(attribute)
11
+ range = ActiveModel::Validations::NumericalityValidator.new(attributes: :fake, in: 1..2)
12
+ uniqueness = ActiveRecord::Validations::UniquenessValidator.new(attributes: :fake)
13
+ allow(assigner.attribute).to receive(:validators).and_return([range, uniqueness])
14
+ values = 4.times.map { assigner.value }
15
+ expect(values).to match_array([1, 2, nil, nil])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::Base do
6
+ let(:attribute) { build_attribute(type: :integer) }
7
+ let(:assigner) { described_class.new(attribute) }
8
+
9
+ describe '#initialize' do
10
+ it 'instantiates an instance' do
11
+ expect(described_class.new(attribute)).to be_a described_class
12
+ end
13
+ end
14
+
15
+ describe '#value' do
16
+ context 'when value should be absent (absence: true)' do
17
+ it 'returns nil' do
18
+ validator = ActiveRecord::Validations::AbsenceValidator.new(attributes: :fake)
19
+ allow(assigner.attribute).to receive(:validators).and_return([validator])
20
+ 10.times { expect(assigner.value).to be_nil }
21
+ end
22
+ end
23
+
24
+ context 'when value should be one of given options (inclusion: { in: %w[foo bar zed] })' do
25
+ context 'when type is a string' do
26
+ it 'returns one of the options' do
27
+ attribute = build_attribute(type: :string)
28
+ validator = ActiveModel::Validations::InclusionValidator.new(attributes: :fake, in: %w[foo bar zed])
29
+ allow(attribute).to receive(:validators).and_return([validator])
30
+ assigner = described_class.new(attribute)
31
+ 10.times { expect(assigner.value).to be_in(%w[foo bar zed]) }
32
+ end
33
+ end
34
+
35
+ context 'when type is an integer' do
36
+ it 'returns one of the options' do
37
+ attribute = build_attribute(type: :integer)
38
+ validator = ActiveModel::Validations::InclusionValidator.new(attributes: :fake, in: [15, 30, 45])
39
+ allow(attribute).to receive(:validators).and_return([validator])
40
+ assigner = described_class.new(attribute)
41
+ 10.times { expect(assigner.value).to be_in([15, 30, 45]) }
42
+ end
43
+ end
44
+
45
+ context 'when inclusion is a range (in: 0.0..1.0)' do
46
+ it 'returns a value included in the range' do
47
+ assigner = described_class.new(attribute)
48
+ validator = ActiveModel::Validations::InclusionValidator.new(attributes: :fake, in: 0.0..1.0)
49
+ allow(attribute).to receive(:validators).and_return([validator])
50
+ 10.times { expect(assigner.value).to be_between(0, 1) }
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'when attribute name is listed in meaningful attributes' do
56
+ context 'when attribute type matches accepted types' do
57
+ it 'returns a meaningful value (example: string "email")' do
58
+ attribute = build_attribute(name: :email, type: :string)
59
+ assigner = described_class.new(attribute)
60
+ 10.times { expect(assigner.value).to match(URI::MailTo::EMAIL_REGEXP) }
61
+ end
62
+
63
+ it 'returns a meaningful value (example: float "latitude")' do
64
+ attribute = build_attribute(name: :latitude, type: :float)
65
+ assigner = described_class.new(attribute)
66
+ expect(assigner.value).to be_a Float
67
+ 10.times { expect(assigner.value.to_s).to match(/-?\d+\.\d{9,}/) }
68
+ end
69
+ end
70
+
71
+ context 'when attribute type does not match accepted types' do
72
+ it 'returns a value that is not meaningful' do
73
+ attribute = build_attribute(name: :latitude, type: :string)
74
+ assigner = described_class.new(attribute)
75
+ expect(assigner.value).to be_a String
76
+ 10.times { expect(assigner.value).not_to match(/-?\d+\.\d{9,}/) }
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::Boolean do
6
+ let(:attribute) { build_attribute(type: :boolean) }
7
+
8
+ describe '#value' do
9
+ it 'returns a Boolean' do
10
+ 10.times { expect(described_class.new(attribute).value).to be_in([true, false]) }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::Date do
6
+ let(:attribute) { build_attribute(type: :date) }
7
+
8
+ describe '#value' do
9
+ context 'when there are no validators' do
10
+ it 'returns a Date' do
11
+ 10.times { expect(described_class.new(attribute).value).to be_a Date }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::Float do
6
+ let(:attribute) { build_attribute(type: :float) }
7
+
8
+ describe '#value' do
9
+ context 'when there are no validators' do
10
+ it 'returns a float' do
11
+ 10.times { expect(described_class.new(attribute).value).to be_a Float }
12
+ end
13
+ end
14
+
15
+ context 'when there is greater_than validator' do
16
+ it 'returns a float greater than the requirement' do
17
+ assigner = described_class.new(attribute)
18
+ validator = ActiveModel::Validations::NumericalityValidator.new(attributes: :fake, greater_than: 1_000)
19
+ allow(attribute).to receive(:validators).and_return([validator])
20
+ 10.times { expect(assigner.value).to be >= 1_000 }
21
+ end
22
+ end
23
+
24
+ context 'when there is less_than validator' do
25
+ it 'returns a float less than the requirement' do
26
+ assigner = described_class.new(attribute)
27
+ validator = ActiveModel::Validations::NumericalityValidator.new(attributes: :fake, less_than: -1_000)
28
+ allow(attribute).to receive(:validators).and_return([validator])
29
+ 10.times { expect(assigner.value).to be < -1_000 }
30
+ end
31
+ end
32
+
33
+ context 'when there is greater_and less_than validators' do
34
+ it 'returns a float greater than and less than the requirements' do
35
+ assigner = described_class.new(attribute)
36
+ validator =
37
+ ActiveModel::Validations::NumericalityValidator.new(attributes: :fake, greater_than: 0, less_than: 1)
38
+ allow(attribute).to receive(:validators).and_return([validator])
39
+ 10.times { expect(assigner.value).to be_between(0, 1).exclusive }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::Integer do
6
+ let(:attribute) { build_attribute(type: :integer) }
7
+
8
+ describe '#value' do
9
+ context 'when there are no validators' do
10
+ it 'returns an integer' do
11
+ 10.times { expect(described_class.new(attribute).value).to be_an Integer }
12
+ end
13
+ end
14
+
15
+ context 'when there is greater_than validator' do
16
+ it 'returns an integer greater than the requirement' do
17
+ assigner = described_class.new(attribute)
18
+ validator = ActiveModel::Validations::NumericalityValidator.new(attributes: :fake, greater_than: 1_000)
19
+ allow(attribute).to receive(:validators).and_return([validator])
20
+ 10.times { expect(assigner.value).to be >= 1_000 }
21
+ end
22
+ end
23
+
24
+ context 'when there is less_than validator' do
25
+ it 'returns an integer less than the requirement' do
26
+ assigner = described_class.new(attribute)
27
+ validator = ActiveModel::Validations::NumericalityValidator.new(attributes: :fake, less_than: -1_000)
28
+ allow(attribute).to receive(:validators).and_return([validator])
29
+ 10.times { expect(assigner.value).to be < -1_000 }
30
+ end
31
+ end
32
+
33
+ context 'when there are less_than and greater_than validators' do
34
+ it 'returns an integer greater than and less than the requirements' do
35
+ assigner = described_class.new(attribute)
36
+ validator =
37
+ ActiveModel::Validations::NumericalityValidator.new(attributes: :fake, greater_than: 1, less_than: 5)
38
+ allow(attribute).to receive(:validators).and_return([validator])
39
+ 10.times { expect(assigner.value).to be_between(1, 5).exclusive }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::String do
6
+ let(:data_model) { DirtySeed::DataModel }
7
+ let(:attribute) { build_attribute(type: :string) }
8
+
9
+ describe '#value' do
10
+ context 'when there are no validators' do
11
+ it 'returns a String' do
12
+ expect(described_class.new(attribute).value).to be_a String
13
+ end
14
+ end
15
+
16
+ context 'when value should match pattern' do
17
+ it 'returns a value matching the pattern' do
18
+ attribute = build_attribute(type: :string)
19
+ assigner = described_class.new(attribute)
20
+ regex = /\w{10}@(hotmail|gmail)\.com/
21
+ validator = ActiveModel::Validations::FormatValidator.new(attributes: :fake, with: regex)
22
+ allow(assigner.attribute).to receive(:validators).and_return([validator])
23
+ 10.times { expect(assigner.value).to match(regex) }
24
+ end
25
+ end
26
+
27
+ context 'when the length has a minimim validation' do
28
+ it 'returns a value with the required length' do
29
+ attribute = build_attribute(type: :string)
30
+ assigner = described_class.new(attribute)
31
+ validator = ActiveRecord::Validations::LengthValidator.new(attributes: :fake, minimum: 5)
32
+ allow(assigner.attribute).to receive(:validators).and_return([validator])
33
+ 10.times { expect(assigner.value.length).to be >= 5 }
34
+ end
35
+ end
36
+
37
+ context 'when the length has a maximum validation' do
38
+ it 'returns a value with the required length' do
39
+ attribute = build_attribute(type: :string)
40
+ assigner = described_class.new(attribute)
41
+ validator = ActiveRecord::Validations::LengthValidator.new(attributes: :fake, maximum: 5)
42
+ allow(assigner.attribute).to receive(:validators).and_return([validator])
43
+ 10.times { expect(assigner.value.length).to be <= 5 }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Assigners::Time do
6
+ let(:attribute) { build_attribute(type: :time) }
7
+
8
+ describe '#value' do
9
+ context 'when there are no validators' do
10
+ it 'returns a Time' do
11
+ 10.times { expect(described_class.new(attribute).value).to be_a Time }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Association do
6
+ let(:model) { DirtySeed::DataModel.charlie }
7
+ let(:reflection) { Charlie.reflections['alfa'] }
8
+ let(:association) { described_class.new(model, reflection) }
9
+
10
+ describe '#initialize' do
11
+ it 'instantiates an instance' do
12
+ expect(association).to be_a described_class
13
+ end
14
+ end
15
+
16
+ describe '#model' do
17
+ it 'returns dirty model' do
18
+ expect(association.model).to eq model
19
+ end
20
+ end
21
+
22
+ describe '#name' do
23
+ it 'returns attribute name' do
24
+ expect(association.name).to eq :alfa
25
+ end
26
+ end
27
+
28
+ describe '#attribute' do
29
+ it 'returns attribute of this association' do
30
+ expect(association.attribute).to eq :alfa_id
31
+ end
32
+ end
33
+
34
+ describe '#associated_models' do
35
+ context 'when the reflection is regular' do
36
+ it 'returns belongs_to association' do
37
+ expect(association.associated_models).to eq [Alfa]
38
+ end
39
+ end
40
+
41
+ context 'when the reflection is polymorphic' do
42
+ it 'returns models associated with has_many or has_one' do
43
+ model = DirtySeed::DataModel.echo
44
+ reflection = Echo.reflections['echoable']
45
+ association = described_class.new(model, reflection)
46
+ expect(association.associated_models).to eq [Alfa, Charlie]
47
+ end
48
+ end
49
+
50
+ context 'when the reflection is cyclic (a belongs to b and b optionnally belongs to a)' do
51
+ it 'returns models accepting this one as polymorphic' do
52
+ model = DirtySeed::DataModel.hotel
53
+ reflection = Hotel.reflections['india']
54
+ association = described_class.new(model, reflection)
55
+ expect(association.associated_models).to eq [India]
56
+
57
+ model = DirtySeed::DataModel.india
58
+ reflection = India.reflections['hotel']
59
+ association = described_class.new(model, reflection)
60
+ expect(association.associated_models).to eq [Hotel]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe DirtySeed::Attribute do
6
+ let(:attribute) { described_class.new(build_model, build_column) }
7
+
8
+ describe '#initialize' do
9
+ it 'instantiates an instance' do
10
+ expect(attribute).to be_a described_class
11
+ end
12
+ end
13
+
14
+ describe '#model' do
15
+ it 'returns dirty model' do
16
+ expect(attribute.model).to be_a DirtySeed::Model
17
+ end
18
+ end
19
+
20
+ describe '#type' do
21
+ context 'when column is a boolean' do
22
+ it 'returns :boolean' do
23
+ attribute = described_class.new(build_model, build_column(type: :boolean))
24
+ expect(attribute.type).to eq :boolean
25
+ end
26
+ end
27
+
28
+ context 'when column is an integer' do
29
+ it 'returns :integer' do
30
+ attribute = described_class.new(build_model, build_column(type: :integer))
31
+ expect(attribute.type).to eq :integer
32
+ end
33
+ end
34
+
35
+ context 'when column is a decimal' do
36
+ it 'returns :float' do
37
+ attribute = described_class.new(build_model, build_column(type: :float))
38
+ expect(attribute.type).to eq :float
39
+ end
40
+ end
41
+
42
+ context 'when column is a string' do
43
+ it 'returns :string' do
44
+ attribute = described_class.new(build_model, build_column(type: :string))
45
+ expect(attribute.type).to eq :string
46
+ end
47
+ end
48
+ end
49
+ end
@@ -6,41 +6,13 @@ RSpec.describe DirtySeed::DataModel do
6
6
  describe '::seed' do
7
7
  context 'when ApplicationRecord is defined' do
8
8
  it 'seeds instances for each model' do
9
- described_class.reset
10
- described_class.seed(1)
11
- # As expected, Juliett can not be seed
12
- [Alfa, Bravo, Charlie, Delta, Echo, Foxtrot, Golf, Hotel, India].each do |active_record_model|
13
- expect(active_record_model.count).to be > 0
14
- end
9
+ expect { described_class.seed(3) }.to change(Alfa, :count).by(3).and change(Golf, :count).by(3)
15
10
  end
16
11
 
17
- it 'logs data' do # rubocop:disable RSpec/ExampleLength
18
- described_class.reset
19
- expect { described_class.seed(8) }.to output(
20
- <<~LOG
21
- Alfa
22
- created: 8
23
- Bravo
24
- created: 8
25
- Charlie
26
- created: 8
27
- Delta
28
- created: 8
29
- Echo
30
- created: 8
31
- Foxtrot
32
- created: 8
33
- Golf
34
- created: 8
35
- Hotel
36
- created: 8
37
- India
38
- created: 8
39
- Juliett
40
- created: 0
41
- errors: Alfa should be some specific alfa, A string should be a specific string, An integer should be a specific integer
42
- LOG
43
- ).to_stdout
12
+ it 'logs data' do
13
+ expect { described_class.seed(1) }.to output(/Alfa/).to_stdout
14
+ expect { described_class.seed(2) }.to output(/seeded: 2/).to_stdout
15
+ expect { described_class.seed(1) }.to output(/(errors:)(.*)(A string should be a specific string)/).to_stdout
44
16
  end
45
17
  end
46
18
 
@@ -52,9 +24,9 @@ RSpec.describe DirtySeed::DataModel do
52
24
  end
53
25
  end
54
26
 
55
- describe '::dirty_models' do
27
+ describe '::models' do
56
28
  it 'returns an array of dirty models representing Active Record models' do
57
- expect(described_class.dirty_models.map(&:name)).to match_array(
29
+ expect(described_class.models.map(&:name)).to match_array(
58
30
  %w[Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett]
59
31
  )
60
32
  end
@@ -79,7 +51,7 @@ RSpec.describe DirtySeed::DataModel do
79
51
  describe '#method_missing' do
80
52
  context 'when method_name matches an ActiveRecord model' do
81
53
  it 'returns the related dirty model' do
82
- dirty_alfa = described_class.dirty_models.find { |dirty_model| dirty_model.model == Alfa }
54
+ dirty_alfa = described_class.models.find { |model| model.model == Alfa }
83
55
  expect(described_class.respond_to_missing?(:alfa)).to be true
84
56
  expect(described_class.alfa).to eq dirty_alfa
85
57
  end