dirty_seed 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
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