fides 1.0.1 → 1.1.0

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