fides 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb5348f0123dc29b821666959c3ac4df69314296
4
+ data.tar.gz: 5cdd818167dc6a69d60167ff8fc78845da405943
5
+ SHA512:
6
+ metadata.gz: 254fcc01368c3c0ab6fc2b39b280bddf927698d39416e74cf829816e47572db6b957b0454cbe9d87a08972f51e6510bcb0bede27a14ec54fadf07cc73ec13d07
7
+ data.tar.gz: 1f3b421f03f3e8a0adb45e90b94ffb2bfa96c539f971b0a02f0eb306c5ddff30c521b38fa1b8c515987aa01f2cec0de74a0a915d343b36605b16a0cc40ecfa9b
data/README.md CHANGED
@@ -66,6 +66,16 @@ If you're using Rails < version 3.1, then use Fides in your migration like this:
66
66
 
67
67
  end
68
68
 
69
+ ## Tests
70
+
71
+ rake test:unit
72
+ rake test:sqlite3
73
+
74
+ To run the postgresql integration tests you must first copy test/config/database.yml.example to test/config/database.yml
75
+ and customize the values for your local postgres installation.
76
+
77
+ rake test:postgresql
78
+
69
79
  ## Caveats
70
80
 
71
81
  Fides assumes the use of Rails conventions, so if you find a case for something that needs overriding,
data/Rakefile CHANGED
@@ -5,6 +5,8 @@ require 'rake/testtask'
5
5
  require 'pg'
6
6
  require 'yaml'
7
7
  require 'sqlite3'
8
+ require 'pry'
9
+ require_relative 'test/integration/db_test'
8
10
 
9
11
  SQLITE3_FILE_PATH = "test/db/fides_test.sqlite3"
10
12
 
@@ -35,21 +37,25 @@ def destroy_sqlite3_db
35
37
  File.delete(SQLITE3_FILE_PATH)
36
38
  end
37
39
 
38
- task :create_databases do
39
- postgres_db(:create => true)
40
- create_sqlite3_db
41
- end
40
+ namespace :test do
42
41
 
43
- task :destroy_databases do
44
- postgres_db(:create => false)
45
- destroy_sqlite3_db
46
- end
42
+ Rake::TestTask.new do |t|
43
+ t.name = :unit
44
+ t.libs << 'lib/fides'
45
+ t.test_files = FileList['test/unit/*_test.rb']
46
+ t.verbose = true
47
+ end
47
48
 
48
- Rake::TestTask.new do |t|
49
- t.name = :run_tests
50
- t.libs << 'lib/fides'
51
- t.test_files = FileList['test/unit/*_test.rb', 'test/integration/*_test.rb']
52
- t.verbose = true
53
- end
49
+ task :postgresql do
50
+ postgres_db(:create => false)
51
+ postgres_db(:create => true)
52
+ Fides.run_common_tests("postgresql")
53
+ end
54
+
55
+ task :sqlite3 do
56
+ # destroy_sqlite3_db
57
+ create_sqlite3_db
58
+ Fides.run_common_tests("sqlite3")
59
+ end
54
60
 
55
- task :test => [:create_databases, :run_tests, :destroy_databases]
61
+ end
data/fides.gemspec CHANGED
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency "minitest", "~> 4.7.0"
29
29
  spec.add_development_dependency "pg"
30
30
  spec.add_development_dependency "sqlite3"
31
+ spec.add_development_dependency "pry"
31
32
  end
data/lib/fides.rb CHANGED
@@ -44,7 +44,6 @@ module Fides
44
44
  return "Fides::#{db_adapter.capitalize}Writer".constantize
45
45
  end
46
46
 
47
- # TODO: Is it safe to just grab the first polymorphic association?
48
47
  def interface_name(model_name)
49
48
  model_name.constantize.reflect_on_all_associations.select { |r| r if r.options[:polymorphic] }.first.name
50
49
  end
@@ -53,4 +52,4 @@ end
53
52
 
54
53
  class ActiveRecord::Migration
55
54
  include Fides
56
- end
55
+ end
@@ -40,6 +40,15 @@ module Fides
40
40
  SELECT CASE
41
41
  }
42
42
 
43
+ sql << 'WHEN ('
44
+
45
+ models.each do |model|
46
+ sql << %{NEW.#{interface_name}_type != '#{model}' }
47
+ sql << 'AND ' unless model == models.last
48
+ end
49
+
50
+ sql << %{) THEN RAISE(ABORT, 'There is no model by that name.') }
51
+
43
52
  models.each do |model|
44
53
  sql << %{
45
54
  WHEN ((NEW.#{interface_name}_type = '#{model}') AND (SELECT id
@@ -62,6 +71,15 @@ module Fides
62
71
  SELECT CASE
63
72
  }
64
73
 
74
+ sql << 'WHEN ('
75
+
76
+ models.each do |model|
77
+ sql << %{NEW.#{interface_name}_type != '#{model}' }
78
+ sql << 'AND ' unless model == models.last
79
+ end
80
+
81
+ sql << %{) THEN RAISE(ABORT, 'There is no model by that name.') }
82
+
65
83
  models.each do |model|
66
84
  sql << %{
67
85
  WHEN ((NEW.#{interface_name}_type = '#{model}') AND (SELECT id
data/lib/fides/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fides
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,7 +1,12 @@
1
1
  require_relative '../test_helper'
2
2
 
3
3
  module Fides
4
- def self.run_common_tests
4
+ def self.run_common_tests(adapter)
5
+ execute_migration(adapter) do
6
+ CreateTestTables.new.change
7
+ AddTriggers.new.up
8
+ end
9
+
5
10
  describe "PostgreSQL database interaction behaviour" do
6
11
  it "raises an exception inserting a polymorphic without a coresponding record" do
7
12
  clothing_article = ClothingArticle.new
@@ -24,6 +29,40 @@ module Fides
24
29
  clothing_article.save
25
30
 
26
31
  assert_raises(ActiveRecord::StatementInvalid) { Senior.find(senior.id).delete }
32
+ assert_raises(ActiveRecord::StatementInvalid) { Senior.find(senior.id).destroy }
33
+ end
34
+
35
+ it "doesn't get in the way of :dependent => :destroy" do
36
+ baby = Baby.new
37
+ baby.name = "Suze"
38
+ baby.save
39
+ baby.reload
40
+
41
+ clothing_article = ClothingArticle.new
42
+ clothing_article.name = "Bloomers"
43
+ clothing_article.wearable_id = baby.id
44
+ clothing_article.wearable_type = "Baby"
45
+ clothing_article.save
46
+ before_destroy_count = ClothingArticle.count
47
+ baby.destroy
48
+
49
+ assert_equal (before_destroy_count - 1), ClothingArticle.count
50
+ end
51
+
52
+ it "does enfoce dependent destroy behaviour if delete is used instead of destroy" do
53
+ baby = Baby.new
54
+ baby.name = "Suze"
55
+ baby.save
56
+ baby.reload
57
+
58
+ clothing_article = ClothingArticle.new
59
+ clothing_article.name = "Bloomers"
60
+ clothing_article.wearable_id = baby.id
61
+ clothing_article.wearable_type = "Baby"
62
+ clothing_article.save
63
+ before_destroy_count = ClothingArticle.count
64
+
65
+ assert_raises(ActiveRecord::StatementInvalid) { baby.delete }
27
66
  end
28
67
 
29
68
  it "allows an insert of a model type specified in #add_polymorphic_triggers" do
@@ -48,19 +87,62 @@ module Fides
48
87
  assert Teenager.find(teenager.id).delete
49
88
  end
50
89
 
51
- it "allows an insert of a model type that wasn't specified in #add_polymorphic_triggers" do
90
+ it "allows a destroy of a record NOT referenced by the polymorphic table" do
91
+ teenager = Teenager.new
92
+ teenager.name = "Johnny"
93
+ teenager.save
94
+ teenager.reload
95
+
96
+ assert Teenager.find(teenager.id).destroy
97
+ end
98
+
99
+ it "does not allow an insert of a model type that wasn't specified in #add_polymorphic_triggers" do
52
100
  clothing_article = ClothingArticle.new
53
101
  clothing_article.name = "Nothing"
54
102
  clothing_article.wearable_id = 123
55
103
  clothing_article.wearable_type = "Zygote"
56
- assert clothing_article.save
104
+
105
+ assert_raises(ActiveRecord::StatementInvalid) { clothing_article.save }
106
+ end
107
+
108
+ it "does not allow an update to a model type that wasn't specified in #add_polymorphic_triggers" do
109
+ baby = Baby.new
110
+ baby.name = "JJ"
111
+ baby.save
112
+ baby.reload
113
+
114
+ clothing_article = ClothingArticle.new
115
+ clothing_article.name = "Onesie"
116
+ clothing_article.wearable_id = baby.id
117
+ clothing_article.wearable_type = "Baby"
118
+ clothing_article.save
119
+ clothing_article.reload
120
+
121
+ clothing_article.wearable_type = "Zygote"
122
+ assert_raises(ActiveRecord::StatementInvalid) { clothing_article.save }
123
+ end
124
+
125
+ it "drops the trigger properly" do
126
+ begin
127
+ execute_migration(adapter) do
128
+ AddTriggers.new.down
129
+ end
130
+ clothing_article = ClothingArticle.new
131
+ clothing_article.name = "Nothing"
132
+ clothing_article.wearable_id = 123
133
+ clothing_article.wearable_type = "Zygote"
134
+
135
+ assert clothing_article.save
136
+ rescue
137
+
138
+ ensure
139
+ execute_migration(adapter) do
140
+ AddTriggers.new.up
141
+ end
142
+ end
57
143
  end
58
144
  end # describe
59
145
  end # run_common_tests
60
146
 
61
- connect_and_migrate_database("postgresql")
62
- run_common_tests
63
147
 
64
- connect_and_migrate_database("sqlite3")
65
- run_common_tests
66
148
  end # Fides
@@ -0,0 +1,9 @@
1
+ class AddTriggers < ActiveRecord::Migration
2
+ def up
3
+ add_polymorphic_triggers(:polymorphic_model => "ClothingArticle", :associated_models => ["Baby", "Senior", "Teenager"])
4
+ end
5
+
6
+ def down
7
+ remove_polymorphic_triggers(:polymorphic_model => "ClothingArticle")
8
+ end
9
+ end
@@ -21,7 +21,5 @@ class CreateTestTables < ActiveRecord::Migration
21
21
  t.string :name
22
22
  t.timestamps
23
23
  end
24
-
25
- add_polymorphic_triggers(:polymorphic_model => "ClothingArticle", :associated_models => ["Baby", "Senior", "Teenager"])
26
24
  end
27
25
  end
@@ -1,4 +1,4 @@
1
1
  class Baby < ActiveRecord::Base
2
2
  self.table_name = 'babies'
3
- has_many :clothing_articles, :as => :wearable
3
+ has_many :clothing_articles, :as => :wearable, :dependent => :destroy
4
4
  end
data/test/test_helper.rb CHANGED
@@ -3,23 +3,22 @@ require 'minitest/pride'
3
3
  require File.expand_path('../../lib/fides.rb', __FILE__)
4
4
  require 'pg'
5
5
  require_relative 'integration/migrations/create_test_tables'
6
+ require_relative 'integration/migrations/add_triggers'
6
7
  require_relative 'integration/models/baby'
7
8
  require_relative 'integration/models/teenager'
8
9
  require_relative 'integration/models/senior'
9
10
  require_relative 'integration/models/clothing_article'
10
11
 
11
-
12
- def connect_and_migrate_database(adapter_name)
12
+ def execute_migration(adapter_name)
13
13
  path = File.join(File.dirname(__FILE__), "config", "database.yml")
14
14
  yaml = YAML.load_file(path)
15
15
  yaml["sqlite3"] = { :adapter => "sqlite3", :database => File.join(File.dirname(__FILE__), "db", "fides_test.sqlite3") }
16
16
  connection_config = yaml[adapter_name]
17
17
 
18
18
  ActiveRecord::Base.establish_connection(connection_config)
19
-
20
19
  Rails.stub :env, "test" do
21
20
  ActiveRecord::Base.stub :configurations, { "test" => { "adapter" => adapter_name } } do
22
- CreateTestTables.new.change
21
+ yield
23
22
  end
24
23
  end
25
24
  end
@@ -36,6 +36,7 @@ describe Fides::Sqlite3Writer do
36
36
  BEFORE INSERT ON pictures
37
37
  BEGIN
38
38
  SELECT CASE
39
+ WHEN (NEW.imageable_type != 'Product' AND NEW.imageable_type != 'Employee' ) THEN RAISE(ABORT, 'There is no model by that name.')
39
40
  WHEN ((NEW.imageable_type = 'Product') AND (SELECT id FROM products WHERE id = NEW.imageable_id) ISNULL) THEN RAISE(ABORT, 'There is no Product with that id.')
40
41
  WHEN ((NEW.imageable_type = 'Employee') AND (SELECT id FROM employees WHERE id = NEW.imageable_id) ISNULL) THEN RAISE(ABORT, 'There is no Employee with that id.')
41
42
  END;
@@ -87,6 +88,7 @@ describe Fides::Sqlite3Writer do
87
88
  BEFORE UPDATE ON pictures
88
89
  BEGIN
89
90
  SELECT CASE
91
+ WHEN (NEW.imageable_type != 'Product' AND NEW.imageable_type != 'Employee' ) THEN RAISE(ABORT, 'There is no model by that name.')
90
92
  WHEN ((NEW.imageable_type = 'Product') AND (SELECT id FROM products WHERE id = NEW.imageable_id) ISNULL) THEN RAISE(ABORT, 'There is no Product with that id.')
91
93
  WHEN ((NEW.imageable_type = 'Employee') AND (SELECT id FROM employees WHERE id = NEW.imageable_id) ISNULL) THEN RAISE(ABORT, 'There is no Employee with that id.')
92
94
  END;
metadata CHANGED
@@ -1,68 +1,60 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fides
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
5
- prerelease:
4
+ version: 1.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Martin Kraft
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-13 00:00:00.000000000 Z
11
+ date: 2013-04-28 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: activerecord
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rails
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: bundler
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
@@ -78,23 +69,20 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rake
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - '>='
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - '>='
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: minitest
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ~>
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ~>
108
95
  - !ruby/object:Gem::Version
@@ -110,33 +97,43 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: pg
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - ! '>='
101
+ - - '>='
116
102
  - !ruby/object:Gem::Version
117
103
  version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ! '>='
108
+ - - '>='
124
109
  - !ruby/object:Gem::Version
125
110
  version: '0'
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: sqlite3
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - ! '>='
115
+ - - '>='
132
116
  - !ruby/object:Gem::Version
133
117
  version: '0'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - ! '>='
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
140
137
  - !ruby/object:Gem::Version
141
138
  version: '0'
142
139
  description: Maintains referential integrity of Rails polymorphic associations.
@@ -162,6 +159,7 @@ files:
162
159
  - test/config/database.yml.example
163
160
  - test/db/.gitkeep
164
161
  - test/integration/db_test.rb
162
+ - test/integration/migrations/add_triggers.rb
165
163
  - test/integration/migrations/create_test_tables.rb
166
164
  - test/integration/models/baby.rb
167
165
  - test/integration/models/clothing_article.rb
@@ -176,33 +174,33 @@ files:
176
174
  homepage: https://github.com/mkraft/fides
177
175
  licenses:
178
176
  - MIT
177
+ metadata: {}
179
178
  post_install_message:
180
179
  rdoc_options: []
181
180
  require_paths:
182
181
  - lib
183
182
  required_ruby_version: !ruby/object:Gem::Requirement
184
- none: false
185
183
  requirements:
186
- - - ! '>='
184
+ - - '>='
187
185
  - !ruby/object:Gem::Version
188
186
  version: '0'
189
187
  required_rubygems_version: !ruby/object:Gem::Requirement
190
- none: false
191
188
  requirements:
192
- - - ! '>='
189
+ - - '>='
193
190
  - !ruby/object:Gem::Version
194
191
  version: '0'
195
192
  requirements: []
196
193
  rubyforge_project:
197
- rubygems_version: 1.8.25
194
+ rubygems_version: 2.0.3
198
195
  signing_key:
199
- specification_version: 3
196
+ specification_version: 4
200
197
  summary: Creates SQL triggers from Rails migrations to enforce the integrity of polymorphic
201
198
  associations at the database level.
202
199
  test_files:
203
200
  - test/config/database.yml.example
204
201
  - test/db/.gitkeep
205
202
  - test/integration/db_test.rb
203
+ - test/integration/migrations/add_triggers.rb
206
204
  - test/integration/migrations/create_test_tables.rb
207
205
  - test/integration/models/baby.rb
208
206
  - test/integration/models/clothing_article.rb