table_warnings 0.0.2
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.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/README.rdoc +26 -0
- data/Rakefile +22 -0
- data/lib/table_warnings/config.rb +11 -0
- data/lib/table_warnings/version.rb +3 -0
- data/lib/table_warnings/warning/blank.rb +23 -0
- data/lib/table_warnings/warning/size.rb +34 -0
- data/lib/table_warnings/warning.rb +29 -0
- data/lib/table_warnings.rb +44 -0
- data/table_warnings.gemspec +24 -0
- data/test/helper.rb +20 -0
- data/test/test_table_warnings.rb +33 -0
- metadata +124 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
=table_warnings
|
|
2
|
+
|
|
3
|
+
NOTE: only for activerecord right now because it uses <tt>count(:conditions => [...])</tt>
|
|
4
|
+
|
|
5
|
+
==How to define warning signs
|
|
6
|
+
|
|
7
|
+
class AutomobileMake < ActiveRecord::Base
|
|
8
|
+
warn_if_blanks_in :name
|
|
9
|
+
warn_if_blanks_in :fuel_efficiency
|
|
10
|
+
warn_unless_size_is :hundreds
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
==How to see warnings for the table
|
|
14
|
+
|
|
15
|
+
?> AutomobileMake.table_warnings
|
|
16
|
+
=> [ "Table is not of expected size" ]
|
|
17
|
+
|
|
18
|
+
==Defense
|
|
19
|
+
|
|
20
|
+
* This is not the same as validations, because those interfere with the saving of individual records
|
|
21
|
+
|
|
22
|
+
==Self-criticism
|
|
23
|
+
|
|
24
|
+
* Maybe this should work work on any class that defines <tt>.all</tt>
|
|
25
|
+
|
|
26
|
+
Copyright 2011 Seamus Abshere
|
data/Rakefile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
Bundler::GemHelper.install_tasks
|
|
3
|
+
|
|
4
|
+
require 'rake'
|
|
5
|
+
require 'rake/testtask'
|
|
6
|
+
Rake::TestTask.new(:test) do |test|
|
|
7
|
+
test.libs << 'lib' << 'test'
|
|
8
|
+
test.pattern = 'test/**/test_*.rb'
|
|
9
|
+
test.verbose = true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
task :default => :test
|
|
13
|
+
|
|
14
|
+
require 'rake/rdoctask'
|
|
15
|
+
Rake::RDocTask.new do |rdoc|
|
|
16
|
+
version = TableWarnings::VERSION
|
|
17
|
+
|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
19
|
+
rdoc.title = "table_warnings #{version}"
|
|
20
|
+
rdoc.rdoc_files.include('README*')
|
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
22
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module TableWarnings
|
|
2
|
+
class Warning
|
|
3
|
+
class Blank < Warning
|
|
4
|
+
attr_reader :column_name
|
|
5
|
+
|
|
6
|
+
def effective_column_names
|
|
7
|
+
if column_name
|
|
8
|
+
[column_name]
|
|
9
|
+
else
|
|
10
|
+
table.column_names
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def messages
|
|
15
|
+
effective_column_names.map do |c|
|
|
16
|
+
if table.count(:conditions => { c => ''}) > 0 or table.count(:conditions => { c => nil }) > 0
|
|
17
|
+
"There are blanks in the `#{c}` column."
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module TableWarnings
|
|
2
|
+
class Warning
|
|
3
|
+
class Size < Warning
|
|
4
|
+
attr_reader :approximate_size
|
|
5
|
+
|
|
6
|
+
def allowed_range
|
|
7
|
+
case approximate_size
|
|
8
|
+
when :few
|
|
9
|
+
1..10
|
|
10
|
+
when :dozens, :tens
|
|
11
|
+
10..100
|
|
12
|
+
when :hundreds
|
|
13
|
+
100..1_000
|
|
14
|
+
when :thousands
|
|
15
|
+
1_000..99_000
|
|
16
|
+
when :hundreds_of_thousands
|
|
17
|
+
100_000..1_000_000
|
|
18
|
+
when :millions
|
|
19
|
+
1_000_000..1_000_000_000
|
|
20
|
+
when Range
|
|
21
|
+
approximate_size
|
|
22
|
+
when Numeric
|
|
23
|
+
approximate_size..approximate_size
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def messages
|
|
28
|
+
unless allowed_range.include? table.count
|
|
29
|
+
"Table is not of expected size (expected: #{allowed_range.to_s}, actual: #{table.count})"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module TableWarnings
|
|
2
|
+
class Warning
|
|
3
|
+
autoload :Blank, 'table_warnings/warning/blank'
|
|
4
|
+
autoload :Size, 'table_warnings/warning/size'
|
|
5
|
+
|
|
6
|
+
attr_reader :table
|
|
7
|
+
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
options.each do |k, v|
|
|
10
|
+
instance_variable_set "@#{k}", v
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_hash
|
|
15
|
+
instance_variables.sort.inject({}) do |memo, ivar_name|
|
|
16
|
+
memo[ivar_name.to_s.sub('@', '')] = instance_variable_get ivar_name
|
|
17
|
+
memo
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def hash
|
|
22
|
+
to_hash.hash
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def eql?(other)
|
|
26
|
+
other.is_a?(Warning) and self.to_hash == other.to_hash
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
|
|
3
|
+
module TableWarnings
|
|
4
|
+
autoload :Config, 'table_warnings/config'
|
|
5
|
+
autoload :Warning, 'table_warnings/warning'
|
|
6
|
+
|
|
7
|
+
def self.config #:nodoc: all
|
|
8
|
+
Config.instance
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Get current warnings on the table.
|
|
12
|
+
def table_warnings
|
|
13
|
+
::TableWarnings.config.warnings[self].map { |w| w.messages }.flatten.compact.sort
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Warn if there are blanks in a certain column.
|
|
17
|
+
#
|
|
18
|
+
# Blank includes both NULL and "" (empty string)
|
|
19
|
+
def warn_if_blanks_in(column_name)
|
|
20
|
+
warning = ::TableWarnings::Warning::Blank.new :table => self, :column_name => column_name
|
|
21
|
+
::TableWarnings.config.warnings[self].add warning
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Warn if there are blanks in ANY column.
|
|
25
|
+
#
|
|
26
|
+
# Blank includes both NULL and "" (empty string)
|
|
27
|
+
def warn_if_any_blanks
|
|
28
|
+
warning = ::TableWarnings::Warning::Blank.new :table => self
|
|
29
|
+
::TableWarnings.config.warnings[self].add warning
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Warn if the number of records falls out of an (approximate) range.
|
|
33
|
+
#
|
|
34
|
+
# Approximations: :few, :tens, :dozens, :hundreds, :thousands, :hundreds_of_thousands, :millions
|
|
35
|
+
# Exact: pass a Range or a Numeric
|
|
36
|
+
def warn_unless_size_is(approximate_size)
|
|
37
|
+
warning = ::TableWarnings::Warning::Size.new :table => self, :approximate_size => approximate_size
|
|
38
|
+
::TableWarnings.config.warnings[self].add warning
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
unless ::ActiveRecord::Base.method_defined? :table_warnings
|
|
43
|
+
::ActiveRecord::Base.extend ::TableWarnings
|
|
44
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
|
3
|
+
require 'table_warnings/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = 'table_warnings'
|
|
7
|
+
s.version = TableWarnings::VERSION
|
|
8
|
+
s.platform = Gem::Platform::RUBY
|
|
9
|
+
s.authors = ['Seamus Abshere']
|
|
10
|
+
s.email = ['seamus@abshere.net']
|
|
11
|
+
s.homepage = 'https://github.com/seamusabshere/table_warnings'
|
|
12
|
+
s.summary = %q{It's called validations to remind people of per-record validations, but it works on the table, and is meant to be used after a table is completely populated.}
|
|
13
|
+
s.description = %q{Validate an entire [ActiveRecord] table, checking for things like blank rows or total number of rows}
|
|
14
|
+
|
|
15
|
+
s.rubyforge_project = 'table_warnings'
|
|
16
|
+
|
|
17
|
+
s.files = `git ls-files`.split("\n")
|
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
|
+
s.require_paths = ['lib']
|
|
21
|
+
s.add_development_dependency 'fastercsv'
|
|
22
|
+
s.add_development_dependency 'earth', '0.3.11'
|
|
23
|
+
s.add_dependency 'activerecord' # for now
|
|
24
|
+
end
|
data/test/helper.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'bundler'
|
|
3
|
+
Bundler.setup
|
|
4
|
+
require 'test/unit'
|
|
5
|
+
require 'active_support/all'
|
|
6
|
+
require 'active_record'
|
|
7
|
+
# thanks authlogic!
|
|
8
|
+
ActiveRecord::Schema.verbose = false
|
|
9
|
+
begin
|
|
10
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
|
11
|
+
rescue ArgumentError
|
|
12
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
|
|
13
|
+
end
|
|
14
|
+
require 'earth'
|
|
15
|
+
Earth.init :automobile, :apply_schemas => true
|
|
16
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
18
|
+
require 'table_warnings'
|
|
19
|
+
class Test::Unit::TestCase
|
|
20
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class AutomobileMake < ActiveRecord::Base
|
|
4
|
+
warn_if_blanks_in :name
|
|
5
|
+
warn_if_blanks_in :fuel_efficiency
|
|
6
|
+
warn_unless_size_is :hundreds
|
|
7
|
+
warn_unless_size_is 100..1000
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class AutomobileFuelType < ActiveRecord::Base
|
|
11
|
+
warn_if_any_blanks
|
|
12
|
+
warn_unless_size_is :few
|
|
13
|
+
warn_unless_size_is 1..6
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
AutomobileMake.create! :name => '', :fuel_efficiency => nil, :fuel_efficiency_units => 'kilometres_per_litre'
|
|
17
|
+
AutomobileMake.create! :name => 'Alfa Romeo', :fuel_efficiency => 10.4075, :fuel_efficiency_units => 'kilometres_per_litre'
|
|
18
|
+
|
|
19
|
+
AutomobileFuelType.create! :name => 'gas'
|
|
20
|
+
AutomobileFuelType.create! :name => 'diesel'
|
|
21
|
+
|
|
22
|
+
class TestTableWarnings < Test::Unit::TestCase
|
|
23
|
+
def test_warn_for_blanks_in_specific_columns
|
|
24
|
+
assert AutomobileMake.table_warnings.one? { |w| w =~ /blanks in.*name.*column/ }
|
|
25
|
+
assert AutomobileMake.table_warnings.one? { |w| w =~ /blanks in.*fuel_efficiency.*column/ }
|
|
26
|
+
end
|
|
27
|
+
def test_warn_of_size
|
|
28
|
+
assert AutomobileMake.table_warnings.many? { |w| w =~ /expected.*size/ }
|
|
29
|
+
end
|
|
30
|
+
def test_warn_for_blanks_in_any_column
|
|
31
|
+
assert AutomobileFuelType.table_warnings.one? { |w| w =~ /blanks in.*code.*column/ }
|
|
32
|
+
end
|
|
33
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: table_warnings
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 27
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 2
|
|
10
|
+
version: 0.0.2
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Seamus Abshere
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-02-18 00:00:00 -06:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: fastercsv
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 3
|
|
30
|
+
segments:
|
|
31
|
+
- 0
|
|
32
|
+
version: "0"
|
|
33
|
+
type: :development
|
|
34
|
+
version_requirements: *id001
|
|
35
|
+
- !ruby/object:Gem::Dependency
|
|
36
|
+
name: earth
|
|
37
|
+
prerelease: false
|
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - "="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
hash: 5
|
|
44
|
+
segments:
|
|
45
|
+
- 0
|
|
46
|
+
- 3
|
|
47
|
+
- 11
|
|
48
|
+
version: 0.3.11
|
|
49
|
+
type: :development
|
|
50
|
+
version_requirements: *id002
|
|
51
|
+
- !ruby/object:Gem::Dependency
|
|
52
|
+
name: activerecord
|
|
53
|
+
prerelease: false
|
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
55
|
+
none: false
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
hash: 3
|
|
60
|
+
segments:
|
|
61
|
+
- 0
|
|
62
|
+
version: "0"
|
|
63
|
+
type: :runtime
|
|
64
|
+
version_requirements: *id003
|
|
65
|
+
description: Validate an entire [ActiveRecord] table, checking for things like blank rows or total number of rows
|
|
66
|
+
email:
|
|
67
|
+
- seamus@abshere.net
|
|
68
|
+
executables: []
|
|
69
|
+
|
|
70
|
+
extensions: []
|
|
71
|
+
|
|
72
|
+
extra_rdoc_files: []
|
|
73
|
+
|
|
74
|
+
files:
|
|
75
|
+
- .gitignore
|
|
76
|
+
- Gemfile
|
|
77
|
+
- README.rdoc
|
|
78
|
+
- Rakefile
|
|
79
|
+
- lib/table_warnings.rb
|
|
80
|
+
- lib/table_warnings/config.rb
|
|
81
|
+
- lib/table_warnings/version.rb
|
|
82
|
+
- lib/table_warnings/warning.rb
|
|
83
|
+
- lib/table_warnings/warning/blank.rb
|
|
84
|
+
- lib/table_warnings/warning/size.rb
|
|
85
|
+
- table_warnings.gemspec
|
|
86
|
+
- test/helper.rb
|
|
87
|
+
- test/test_table_warnings.rb
|
|
88
|
+
has_rdoc: true
|
|
89
|
+
homepage: https://github.com/seamusabshere/table_warnings
|
|
90
|
+
licenses: []
|
|
91
|
+
|
|
92
|
+
post_install_message:
|
|
93
|
+
rdoc_options: []
|
|
94
|
+
|
|
95
|
+
require_paths:
|
|
96
|
+
- lib
|
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
98
|
+
none: false
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
hash: 3
|
|
103
|
+
segments:
|
|
104
|
+
- 0
|
|
105
|
+
version: "0"
|
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
|
+
none: false
|
|
108
|
+
requirements:
|
|
109
|
+
- - ">="
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
hash: 3
|
|
112
|
+
segments:
|
|
113
|
+
- 0
|
|
114
|
+
version: "0"
|
|
115
|
+
requirements: []
|
|
116
|
+
|
|
117
|
+
rubyforge_project: table_warnings
|
|
118
|
+
rubygems_version: 1.3.7
|
|
119
|
+
signing_key:
|
|
120
|
+
specification_version: 3
|
|
121
|
+
summary: It's called validations to remind people of per-record validations, but it works on the table, and is meant to be used after a table is completely populated.
|
|
122
|
+
test_files:
|
|
123
|
+
- test/helper.rb
|
|
124
|
+
- test/test_table_warnings.rb
|