data_works 0.1.1

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.
@@ -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
+