active_sanity 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,2 +1,16 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ task :default => :features
5
+
6
+ desc "Run features"
7
+ task :features do
8
+ raise "Failed!" unless system('bundle exec cucumber features')
9
+ end
10
+
11
+ desc "Clean test rails app"
12
+ task :clean do
13
+ if system('rm -r test/rails_app')
14
+ puts "test/rails_app deleted successfully"
15
+ end
16
+ end
@@ -9,7 +9,7 @@ Feature: Check sanity
9
9
 
10
10
  Scenario: Check sanity on empty database
11
11
  When I run "rake db:check_sanity"
12
- Then I should see "Checking the following models: InvalidRecord, Category, Post, User"
12
+ Then I should see "Checking the following models: Category, InvalidRecord, Post, User"
13
13
  Then I should not see any invalid records
14
14
 
15
15
  Scenario: Check sanity on database with valid records
@@ -19,8 +19,8 @@ Feature: Check sanity
19
19
 
20
20
  Scenario: Check sanity on database with invalid records
21
21
  Given the database contains a few valid records
22
- And the first user's username is empty and the first post category_id is nil
22
+ And the first author's username is empty and the first post category_id is nil
23
23
  When I run "rake db:check_sanity"
24
24
  Then I should see the following invalid records:
25
- | User | 1 | {:username=>["can't be blank", "is too short (minimum is 3 characters)"]} |
25
+ | User | 1 | {:username=>["can't be blank", "is too short (minimum is 3 characters)", "can't be blank", "can't be blank", "is too short (minimum is 3 characters)"]} |
26
26
  | Post | 1 | {:category=>["can't be blank"]} |
@@ -9,7 +9,7 @@ Feature: Check sanity with db storage
9
9
 
10
10
  Scenario: Check sanity on empty database
11
11
  When I run "rake db:check_sanity"
12
- Then I should see "Checking the following models: InvalidRecord, Category, Post, User"
12
+ Then I should see "Checking the following models: Category, InvalidRecord, Post, User"
13
13
  Then the table "invalid_records" should be empty
14
14
 
15
15
  Scenario: Check sanity on database with valid records
@@ -19,7 +19,7 @@ Feature: Check sanity with db storage
19
19
 
20
20
  Scenario: Check sanity on database with invalid records
21
21
  Given the database contains a few valid records
22
- And the first user's username is empty and the first post category_id is nil
22
+ And the first author's username is empty and the first post category_id is nil
23
23
  When I run "rake db:check_sanity"
24
24
  Then the table "invalid_records" should contain:
25
25
  | User | 1 | {:username=>["is too short (minimum is 3 characters)"]} |
@@ -27,13 +27,13 @@ Feature: Check sanity with db storage
27
27
 
28
28
  Scenario: Check sanity on database with invalid records now valid
29
29
  Given the database contains a few valid records
30
- And the first user's username is empty and the first post category_id is nil
30
+ And the first author's username is empty and the first post category_id is nil
31
31
  When I run "rake db:check_sanity"
32
32
  Then the table "invalid_records" should contain:
33
33
  | User | 1 | {:username=>["is too short (minimum is 3 characters)"]} |
34
34
  | Post | 1 | {:category=>["can't be blank"]} |
35
35
 
36
- Given the first user's username is "Greg"
36
+ Given the first author's username is "Greg"
37
37
  When I run "rake db:check_sanity"
38
38
  Then the table "invalid_records" should contain:
39
39
  | Post | 1 | {:category=>["can't be blank"]} |
@@ -41,7 +41,7 @@ Feature: Check sanity with db storage
41
41
 
42
42
  Scenario: Check sanity on database with invalid records that were invalid for different reasons earlier
43
43
  Given the database contains a few valid records
44
- And the first user's username is empty and the first post category_id is nil
44
+ And the first author's username is empty and the first post category_id is nil
45
45
  When I run "rake db:check_sanity"
46
46
  Then the table "invalid_records" should contain:
47
47
  | User | 1 | {:username=>["is too short (minimum is 3 characters)"]} |
@@ -30,21 +30,21 @@ Given /^I have a rails app using 'active_sanity' with db storage$/ do
30
30
  end
31
31
 
32
32
  Given /^the database contains a few valid records$/ do
33
- User.create!(:first_name => "Greg", :last_name => "Bell", :username => "gregbell")
34
- User.create!(:first_name => "Sam", :last_name => "Vincent", :username => "samvincent")
33
+ Author.create!(:first_name => "Greg", :last_name => "Bell", :username => "gregbell")
34
+ Publisher.create!(:first_name => "Sam", :last_name => "Vincent", :username => "samvincent")
35
35
  Category.create!(:name => "Uncategorized")
36
- Post.create!(:author => User.first, :category => Category.first,
37
- :title => "How ActiveAdmin changed the world", :body => "Only gods knows how...",
36
+ Post.create!(:author => Author.first, :category => Category.first,
37
+ :title => "How ActiveAdmin changed the world", :body => "Lot of love.",
38
38
  :published_at => 4.years.from_now)
39
39
  end
40
40
 
41
- Given /^the first user's username is empty and the first post category_id is nil$/ do
42
- User.first.update_attribute(:username, "")
41
+ Given /^the first author's username is empty and the first post category_id is nil$/ do
42
+ Author.first.update_attribute(:username, "")
43
43
  Post.first.update_attribute(:category_id, nil)
44
44
  end
45
45
 
46
- Given /^the first user's username is "([^"]*)"$/ do |username|
47
- User.first.update_attribute('username', username)
46
+ Given /^the first author's username is "([^"]*)"$/ do |username|
47
+ Author.first.update_attribute('username', username)
48
48
  end
49
49
 
50
50
  Given /^the first post category is set$/ do
@@ -4,17 +4,20 @@ require 'rubygems'
4
4
  require "bundler"
5
5
  Bundler.setup
6
6
 
7
- system("rm ./test/rails_app/db/migrate/*create_invalid_records.rb")
8
-
9
- raise unless File.directory?("test/rails_app") && system("cd test/rails_app && rake db:drop db:create db:migrate")
7
+ if File.directory?("test/rails_app")
8
+ Dir.chdir("test/rails_app") do
9
+ raise unless system("rm -f db/migrate/*create_invalid_records.rb && rake db:drop db:create db:migrate")
10
+ end
11
+ end
10
12
 
11
13
  After do
12
14
  # Reset DB!
13
- User.delete_all
14
- Category.delete_all
15
- Post.delete_all
16
- InvalidRecord.delete_all if InvalidRecord.table_exists?
17
- %w(users categories posts invalid_records).each do |table|
18
- ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence WHERE name='#{table}'")
15
+ tables = ['categories', 'invalid_records', 'posts', 'users']
16
+ conn = ActiveRecord::Base.connection
17
+ tables.each do |table|
18
+ if conn.table_exists?(table)
19
+ conn.execute("DELETE FROM '#{table}'")
20
+ conn.execute("DELETE FROM sqlite_sequence WHERE name='#{table}'")
21
+ end
19
22
  end
20
23
  end
@@ -8,30 +8,63 @@ module ActiveSanity
8
8
  puts "Sanity Check"
9
9
  puts "Checking the following models: #{models.join(', ')}"
10
10
 
11
+ # TODO: Wouldnt this list already be checked by the next all records call if those records do exist?
12
+ # This will validate and destroy the records that either dont exist currently, or are now valid. But the ones are continue to be invalid - these will
13
+ # have been run through the validation process twice
11
14
  check_previously_invalid_records
12
15
  check_all_records
13
16
  end
14
17
 
18
+ # @return [Array] of [ActiveRecord::Base] direct descendants
15
19
  def models
16
- # Ensure ActiveRecord::Base is aware of all models under
17
- # app/models
18
- Dir["#{Rails.root}/app/models/**/*.rb"].each do |file_path|
19
- require file_path rescue nil
20
- end
21
-
22
- @models ||= ActiveRecord::Base.subclasses
20
+ return @models if @models
21
+
22
+ load_all_models
23
+
24
+ @models ||= direct_active_record_base_descendants
23
25
  end
24
26
 
25
27
  protected
26
28
 
29
+ # Require all files under /app/models.
30
+ # All models under /lib are required when the rails app loads.
31
+ def load_all_models
32
+ Dir["#{Rails.root}/app/models/**/*.rb"].each { |file_path| require file_path rescue nil }
33
+ end
34
+
35
+ # @return [Array] of direct ActiveRecord::Base descendants.
36
+ # Example:
37
+ # The following tree:
38
+ # ActiveRecord::Base
39
+ # |
40
+ # |- User
41
+ # |- Account
42
+ # | |
43
+ # | |- PersonalAccount
44
+ # | |- BusinessAccount
45
+ #
46
+ # Should return: [Account, User]
47
+ def direct_active_record_base_descendants
48
+ ActiveRecord::Base.descendants.select(&:descends_from_active_record?).sort_by(&:name)
49
+ end
50
+
51
+ # Remove records that are now valid from the list of invalid records.
27
52
  def check_previously_invalid_records
28
53
  return unless InvalidRecord.table_exists?
29
54
 
30
55
  InvalidRecord.find_each do |invalid_record|
31
- invalid_record.destroy if invalid_record.record.valid?
56
+ begin
57
+ invalid_record.destroy if invalid_record.record.valid?
58
+ rescue
59
+ # Record does not exists.
60
+ invalid_record.delete
61
+ end
32
62
  end
33
63
  end
34
64
 
65
+ # Go over every single record. When the record is not valid
66
+ # log it to STDOUT and into the invalid_records table if it exists.
67
+ #
35
68
  def check_all_records
36
69
  models.each do |model|
37
70
  begin
@@ -54,22 +87,30 @@ module ActiveSanity
54
87
  store_invalid_record(record)
55
88
  end
56
89
 
90
+ # Say that the record is invalid. Example:
91
+ #
92
+ # Account | 10 | :name => "Can't be blank"
57
93
  def log_invalid_record(record)
58
- puts record.class.to_s + " | " + record.id.to_s + " | " + pretty_errors(record)
94
+ puts "#{type_of(record)} | #{record.id} | #{pretty_errors(record)}"
59
95
  end
60
-
96
+
97
+ # Store invalid record in InvalidRecord table if it exists
61
98
  def store_invalid_record(record)
62
99
  return unless InvalidRecord.table_exists?
63
100
 
64
- invalid_record = InvalidRecord.where(:record_type => record.type, :record_id => record.id).first
101
+ invalid_record = InvalidRecord.where(:record_type => type_of(record), :record_id => record.id).first
65
102
  invalid_record ||= InvalidRecord.new
66
103
  invalid_record.record = record
67
104
  invalid_record.validation_errors = record.errors
68
105
  invalid_record.save!
69
106
  end
70
107
 
108
+ def type_of(record)
109
+ record.class.base_class
110
+ end
111
+
71
112
  def pretty_errors(record)
72
- record.errors.inspect.sub(/^#<OrderedHash /, '').sub(/>$/, '')
113
+ record.errors.inspect.sub(/^#<OrderedHash (.*)>$/, '\1')
73
114
  end
74
115
  end
75
116
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveSanity
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -1,5 +1,7 @@
1
1
 
2
2
  # Generate some test models
3
+
4
+ # Post
3
5
  generate :model, "post title:string body:text published_at:datetime author_id:integer category_id:integer"
4
6
  post_code = <<-CODE
5
7
  belongs_to :author, :class_name => 'User'
@@ -10,7 +12,17 @@ post_code = <<-CODE
10
12
  CODE
11
13
  inject_into_file 'app/models/post.rb', post_code, :after => "class Post < ActiveRecord::Base\n"
12
14
 
13
- generate :model, "user first_name:string last_name:string username:string"
15
+ # Category
16
+ generate :model, 'category name:string description:text'
17
+ category_code = <<-CODE
18
+ has_many :posts
19
+
20
+ validates_presence_of :name
21
+ CODE
22
+ inject_into_file 'app/models/category.rb', category_code, :after => "class Category < ActiveRecord::Base\n"
23
+
24
+ # User
25
+ generate :model, "user first_name:string last_name:string username:string type:string"
14
26
  user_code = <<-CODE
15
27
  has_many :posts, :foreign_key => 'author_id'
16
28
 
@@ -19,14 +31,13 @@ user_code = <<-CODE
19
31
  CODE
20
32
  inject_into_file 'app/models/user.rb', user_code, :after => "class User < ActiveRecord::Base\n"
21
33
 
22
- generate :model, 'category name:string description:text'
23
- category_code = <<-CODE
24
- has_many :posts
34
+ # Author < User
35
+ create_file 'app/models/author.rb', "class Author < User; end"
36
+ # Publisher < User
37
+ create_file 'app/models/publisher.rb', "class Publisher < User; end"
25
38
 
26
- validates_presence_of :name
27
- CODE
28
- inject_into_file 'app/models/category.rb', category_code, :after => "class Category < ActiveRecord::Base\n"
29
39
 
40
+ # NotAModel
30
41
  create_file 'app/models/not_a_model.rb', "class NotAModel; end"
31
42
 
32
43
  # Add active_sanity
@@ -34,4 +45,3 @@ append_file 'Gemfile', "gem 'active_sanity', :path => '../../'"
34
45
 
35
46
  run "bundle"
36
47
  rake "db:migrate"
37
-
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_sanity
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - VersaPay
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-03-30 00:00:00 -07:00
19
+ date: 2011-09-06 00:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency