data_works 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ # data_works needs its own set of tables and ActiveRecord models to test with.
4
+ require_relative 'test_tables'
5
+ DataWorks::TestTables.create!
6
+ require_relative 'test_models'
7
+
8
+ module DataWorks
9
+ class StaleRelationshipChecker
10
+ def self.check!
11
+ true # For self testing purposes we can just state that the data model has not changed
12
+ end
13
+ end
14
+ end
15
+
16
+ DataWorks.configure do |config|
17
+
18
+ config.necessary_parents = {
19
+ address: [:pet_profile],
20
+ agency: [],
21
+ bell_toy: [{ :pet => :pet_bird }],
22
+ hooman_toy: [:pet],
23
+ kind: [],
24
+ pet: [],
25
+ pet_bird: [],
26
+ pet_food: [],
27
+ pet_profile: [:pet],
28
+ pet_sitter: [:agency, :kind],
29
+ pet_sitting_patronage: [:pet_sitter, :pet],
30
+ tag: [:pet],
31
+ toy: [:pet],
32
+ album: [],
33
+ product: [],
34
+ picture: [{ :imageable => :product }, :album],
35
+ }
36
+
37
+ config.autocreated_children = {
38
+ }
39
+ end
40
+
41
+ class TheDataWorks < DataWorks::Base
42
+ end
43
+
44
+ RSpec.configure do |config|
45
+ config.include FactoryGirl::Syntax::Methods
46
+ end
@@ -0,0 +1,106 @@
1
+ #*******************************************************************************
2
+ # For testing basic associations.
3
+ #*******************************************************************************
4
+
5
+ class Pet < ActiveRecord::Base
6
+ has_many :toys
7
+ has_one :pet_tag
8
+ has_one :pet_profile
9
+ has_one :address, through: :pet_profile
10
+ # We explicitly name the join table so that this code works with both Rails 3 and Rails 4.
11
+ has_and_belongs_to_many :pet_foods, join_table: 'pet_foods_pets'
12
+ has_many :pet_sitting_patronages
13
+ has_many :pet_sitters, through: :pet_sitting_patronages
14
+ end
15
+
16
+ class Toy < ActiveRecord::Base
17
+ validates :name, length: { minimum: 3 }
18
+ belongs_to :pet
19
+ end
20
+
21
+ class PetTag < ActiveRecord::Base
22
+ belongs_to :pet
23
+ end
24
+
25
+ class PetFood < ActiveRecord::Base
26
+ # Rails 3 expects the join table to be called pet_foods_pets
27
+ # Rails 4 expects the join table to be called pet_foods_pets
28
+ # We explicitly name the join table so that this code works with both Rails 3 and Rails 4.
29
+ has_and_belongs_to_many :pets, join_table: 'pet_foods_pets'
30
+ end
31
+
32
+ class Agency < ActiveRecord::Base
33
+ has_many :pet_sitters
34
+ end
35
+
36
+ class Kind < ActiveHash::Base
37
+ self.data = [
38
+ {:id => 1, :name => "Amateur"},
39
+ {:id => 2, :name => "Professional"}
40
+ ]
41
+ end
42
+
43
+ class PetSitter < ActiveRecord::Base
44
+ extend ActiveHash::Associations::ActiveRecordExtensions
45
+ belongs_to :kind
46
+ belongs_to :agency
47
+ has_many :pet_sitting_patronages
48
+ has_many :pets, through: :pet_sitting_patronages
49
+ end
50
+
51
+ class PetSittingPatronage < ActiveRecord::Base
52
+ belongs_to :pet
53
+ belongs_to :pet_sitter
54
+ end
55
+
56
+ class PetProfile < ActiveRecord::Base
57
+ belongs_to :pet
58
+ has_one :address
59
+ end
60
+
61
+ class Address < ActiveRecord::Base
62
+ belongs_to :pet_profile
63
+ end
64
+
65
+ #*******************************************************************************
66
+ # For testing polymorphic associations and custom-named foreign keys.
67
+ #
68
+
69
+ class Picture < ActiveRecord::Base
70
+ belongs_to :imageable, polymorphic: true
71
+ belongs_to :album, foreign_key: 'picture_album_id'
72
+ end
73
+
74
+ class Product < ActiveRecord::Base
75
+ has_many :pictures, as: :imageable
76
+ end
77
+
78
+ class Album < ActiveRecord::Base
79
+ has_many :pictures, foreign_key: 'picture_album_id'
80
+ end
81
+
82
+
83
+
84
+ # #*******************************************************************************
85
+ # # For testing denormalized data structures.
86
+ # #
87
+
88
+ # class Owner < ActiveRecord::Base
89
+ # has_many :vehicles
90
+ # has_many :amenities # this is not normalized, you wouldn't normally do this
91
+ # end
92
+
93
+ # class Vehicle < ActiveRecord::Base
94
+ # has_many :amenities
95
+ # belongs_to :owner
96
+ # end
97
+
98
+ # class Amenity < ActiveRecord::Base
99
+ # belongs_to :vehicle
100
+ # belongs_to :owner # this is not normalized, you wouldn't normally do this
101
+ # has_one :warranty
102
+ # end
103
+
104
+ # class Warranty < ActiveRecord::Base
105
+ # belongs_to :amenity
106
+ # end
@@ -0,0 +1,120 @@
1
+ module DataWorks
2
+ class TestTables
3
+
4
+ def self.create!
5
+ return if @already_created_tables
6
+ ActiveRecord::Migration.class_eval do
7
+ suppress_messages do
8
+
9
+ create_table :agencies, force: true do |t|
10
+ t.string :name, null: false
11
+ t.timestamps null: false
12
+ end
13
+
14
+ create_table :addresses, force: true do |t|
15
+ t.string :street, null: false
16
+ t.string :city, null: false
17
+ t.string :state, null: false
18
+ t.integer :pet_profile_id, null: false
19
+ t.timestamps null: false
20
+ end
21
+
22
+ create_table :pet_foods, force: true do |t|
23
+ t.string :name, null: false
24
+ t.timestamps null: false
25
+ end
26
+
27
+ create_table :pet_foods_pets, force: true, id: false do |t|
28
+ t.integer :pet_id, null: false
29
+ t.integer :pet_food_id, null: false
30
+ end
31
+
32
+ create_table :pet_profiles, force: true do |t|
33
+ t.string :description, null: false
34
+ t.string :nickname
35
+ t.integer :pet_id, null: false
36
+ t.timestamps null: false
37
+ end
38
+
39
+ create_table :pet_sitters, force: true do |t|
40
+ t.string :name, null: false
41
+ t.integer :agency_id, null: false
42
+ t.integer :kind_id, null: false
43
+ t.timestamps null: false
44
+ end
45
+
46
+ create_table :pet_sitting_patronages, force: true do |t|
47
+ t.integer :pet_id, null: false
48
+ t.integer :pet_sitter_id, null: false
49
+ t.timestamps null: false
50
+ end
51
+
52
+ create_table :pet_tags, force: true do |t|
53
+ t.string :registered_name, null: false
54
+ t.integer :pet_id, null: false
55
+ t.timestamps null: false
56
+ end
57
+
58
+ create_table :pets, force: true do |t|
59
+ t.string :name, null: false
60
+ t.string :kind, null: false
61
+ t.integer :birth_year
62
+ t.timestamps null: false
63
+ end
64
+
65
+ create_table :toys, force: true do |t|
66
+ t.string :name
67
+ t.string :kind
68
+ t.integer :pet_id
69
+ t.timestamps null: false
70
+ end
71
+
72
+ create_table :albums, force: true do |t|
73
+ t.string :name, null: false
74
+ t.timestamps null: false
75
+ end
76
+
77
+ create_table :pictures, force: true do |t|
78
+ t.string :name
79
+ t.integer :imageable_id
80
+ t.string :imageable_type
81
+ t.integer :picture_album_id
82
+ t.timestamps null: false
83
+ end
84
+
85
+ create_table :products, force: true do |t|
86
+ t.string :name
87
+ t.timestamps null: false
88
+ end
89
+
90
+ # create_table :amenities, force: true do |t|
91
+ # t.string :name
92
+ # t.integer :vehicle_id
93
+ # t.integer :owner_id
94
+ # t.timestamps null: false
95
+ # end
96
+
97
+ # create_table :owners, force: true do |t|
98
+ # t.string :name, null: false
99
+ # t.timestamps null: false
100
+ # end
101
+
102
+ # create_table :vehicles, force: true do |t|
103
+ # t.string :name
104
+ # t.integer :owner_id
105
+ # t.timestamps null: false
106
+ # end
107
+
108
+ # create_table :warranties, force: true do |t|
109
+ # t.string :name
110
+ # t.integer :amenity_id
111
+ # t.timestamps null: false
112
+ # end
113
+
114
+ end
115
+ end
116
+ @already_created_tables = true
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1,37 @@
1
+ # Anywhere you need fake string data, use this method.
2
+ def fake_string
3
+ words = []
4
+ (rand(2)+2).times { words << DataFaker.hawaiian_word }
5
+ words.join(' ')
6
+ end
7
+
8
+ # Don't use this method, use fake_string instead.
9
+ # Ok, you win, in the situation you described fake_word
10
+ # makes more sense. Here you go, use it if you need to.
11
+ def fake_word
12
+ DataFaker.hawaiian_word
13
+ end
14
+
15
+ # Basically, this is the faker gem + a shrink ray.
16
+ class DataFaker
17
+
18
+ HAWAIIAN_VOWELS = %w( a e i o u )
19
+
20
+ HAWAIIAN_CONSONANTS = %w( h k l m n p t w )
21
+
22
+ def self.hawaiian_syllable
23
+ s = ''
24
+ if rand(100) < 90
25
+ s << HAWAIIAN_CONSONANTS.sample
26
+ end
27
+ s << HAWAIIAN_VOWELS.sample
28
+ s
29
+ end
30
+
31
+ def self.hawaiian_word
32
+ word = ''
33
+ (rand(3)+3).times { word << hawaiian_syllable }
34
+ word
35
+ end
36
+
37
+ end
@@ -0,0 +1,108 @@
1
+ require_relative "helper/data_works_spec_helper"
2
+
3
+ describe DataWorks::Relationships do
4
+ describe "#necessary_parents_for" do
5
+ describe "pet" do
6
+ it "returns an empty collection" do
7
+ expect(DataWorks::Relationships.necessary_parents_for(:pet)).to be_empty
8
+ end
9
+ end
10
+
11
+ describe "pet_food" do
12
+ it "returns an empty collection" do
13
+ expect(DataWorks::Relationships.necessary_parents_for(:pet_food)).to be_empty
14
+ end
15
+ end
16
+
17
+ describe "agency" do
18
+ it "returns an empty collection" do
19
+ expect(DataWorks::Relationships.necessary_parents_for(:agency)).to be_empty
20
+ end
21
+ end
22
+
23
+ describe "toy" do
24
+ it "returns a collection with a single parent object " do
25
+ expect(DataWorks::Relationships.necessary_parents_for(:toy).count).to eq 1
26
+ end
27
+ it "returns a parent object with #association_name => pet" do
28
+ parents = DataWorks::Relationships.necessary_parents_for(:toy)
29
+ expect(parents.first.association_name).to eq(:pet)
30
+ end
31
+ it "returns a parent object with #model_name => pet" do
32
+ parents = DataWorks::Relationships.necessary_parents_for(:toy)
33
+ expect(parents.first.model_name).to eq(:pet)
34
+ end
35
+ end
36
+
37
+ describe "tag" do
38
+ it "returns a collection with a single parent object " do
39
+ expect(DataWorks::Relationships.necessary_parents_for(:tag).count).to eq 1
40
+ end
41
+ it "returns a parent object with #association_name => pet" do
42
+ parents = DataWorks::Relationships.necessary_parents_for(:tag)
43
+ expect(parents.first.association_name).to eq(:pet)
44
+ end
45
+ it "returns a parent object with #model_name => pet" do
46
+ parents = DataWorks::Relationships.necessary_parents_for(:tag)
47
+ expect(parents.first.model_name).to eq(:pet)
48
+ end
49
+ end
50
+
51
+ describe "pet_profile" do
52
+ it "returns a collection with a single parent object " do
53
+ expect(DataWorks::Relationships.necessary_parents_for(:pet_profile).count).to eq 1
54
+ end
55
+ it "returns a parent object with #association_name => pet" do
56
+ parents = DataWorks::Relationships.necessary_parents_for(:pet_profile)
57
+ expect(parents.first.association_name).to eq(:pet)
58
+ end
59
+ it "returns a parent object with #model_name => pet" do
60
+ parents = DataWorks::Relationships.necessary_parents_for(:pet_profile)
61
+ expect(parents.first.model_name).to eq(:pet)
62
+ end
63
+ end
64
+
65
+ describe "pet_sitter" do
66
+ it "returns a collection with a single parent object " do
67
+ expect(DataWorks::Relationships.necessary_parents_for(:pet_sitter).count).to eq 2
68
+ end
69
+ it "returns a parent object with #association_name => agency" do
70
+ parents = DataWorks::Relationships.necessary_parents_for(:pet_sitter)
71
+ expect(parents.first.association_name).to eq(:agency)
72
+ end
73
+ it "returns a parent object with #model_name => agency" do
74
+ parents = DataWorks::Relationships.necessary_parents_for(:pet_sitter)
75
+ expect(parents.first.model_name).to eq(:agency)
76
+ end
77
+ end
78
+
79
+ describe "address" do
80
+ it "returns a collection with a single parent object " do
81
+ expect(DataWorks::Relationships.necessary_parents_for(:address).count).to eq 1
82
+ end
83
+ it "returns a parent object with #association_name => pet_profile" do
84
+ parents = DataWorks::Relationships.necessary_parents_for(:address)
85
+ expect(parents.first.association_name).to eq(:pet_profile)
86
+ end
87
+ it "returns a parent object with #model_name => pet_profile" do
88
+ parents = DataWorks::Relationships.necessary_parents_for(:address)
89
+ expect(parents.first.model_name).to eq(:pet_profile)
90
+ end
91
+ end
92
+
93
+ describe "pet_sitting_patronage" do
94
+ it "returns a collection with two parent objects" do
95
+ expect(DataWorks::Relationships.necessary_parents_for(:pet_sitting_patronage).count).to eq 2
96
+ end
97
+ it "returns an array of parent objects with #association_names => pet_sitter, pet" do
98
+ parents = DataWorks::Relationships.necessary_parents_for(:pet_sitting_patronage)
99
+ expect(parents.map(&:association_name)).to contain_exactly(:pet_sitter, :pet)
100
+ end
101
+ it "returns an array of parent objects with #model_names => pet_sitter, pet" do
102
+ parents = DataWorks::Relationships.necessary_parents_for(:pet_sitting_patronage)
103
+ expect(parents.map(&:model_name)).to contain_exactly(:pet_sitter, :pet)
104
+ end
105
+ end
106
+ end
107
+ end
108
+
@@ -0,0 +1,35 @@
1
+ require_relative "helper/data_works_spec_helper"
2
+
3
+ describe 'DataWorks#set_restriction' do
4
+ let!(:data) { TheDataWorks.new }
5
+
6
+ describe 'setting a restriction using the metheod/registry option'do
7
+ let!(:darth_cuddles) { data.add_pet }
8
+ let!(:kittylo_ren) { data.add_pet }
9
+
10
+ it 'restricts the parent record for new children to the given object' do
11
+ death_star = data.add_toy
12
+ data.set_restriction(for_model: :pet, to: kittylo_ren)
13
+ star_killer = data.add_toy
14
+ expect(death_star.pet).to eq darth_cuddles
15
+ expect(star_killer.pet).to eq kittylo_ren
16
+ end
17
+ end
18
+
19
+ describe 'setting a restriction using the block option'do
20
+ let!(:darth_cuddles) { data.add_pet }
21
+ let!(:kittylo_ren) { data.add_pet }
22
+
23
+ it 'restricts the parent record for new children to the given object' do
24
+ death_star = data.add_toy
25
+ star_killer = data.set_restriction(for_model: :pet, to: kittylo_ren) do
26
+ data.add_toy
27
+ end
28
+ wookie_doll = data.add_toy
29
+ expect(death_star.pet).to eq darth_cuddles
30
+ expect(wookie_doll.pet).to eq darth_cuddles
31
+ expect(star_killer.pet).to eq kittylo_ren
32
+ end
33
+ end
34
+ end
35
+