activerecord-testcase 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0afa741f8b2b41d33f73b22d4ce72a91d0310696
4
+ data.tar.gz: c5b9cfb343c779c9de92514ef2ab7839dae2617c
5
+ SHA512:
6
+ metadata.gz: e3ad0507e99021a88b78c444192b2fcca18fd059360c5875dfe5b0cfea597cbcfd5e279a7002fa9a5e5bfaef1491a59a8714c7554f102338da04a5570c759cdf
7
+ data.tar.gz: 764878a2a42af7f37cc37a9de28973aabb639f96b48aac531d590dabc8fa67a005500367cde35ee026ec78b95d7ef485c0f59a2c29718ba1e133538258aec883
@@ -0,0 +1,4 @@
1
+ lib/**/*.rb
2
+ README.rdoc
3
+ ChangeLog.rdoc
4
+ LICENSE.txt
@@ -0,0 +1,2 @@
1
+ html/
2
+ pkg/
@@ -0,0 +1,4 @@
1
+ === 0.1.0 / 2015-01-16
2
+
3
+ * Initial release:
4
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2004-2015 David Heinemeier Hansson
2
+
3
+ Copyright (c) 2015 Ilia Lobsanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ = activerecord-testcase
2
+
3
+ * {Homepage}[https://rubygems.org/gems/activerecord-testcase]
4
+ * {Documentation}[http://rubydoc.info/gems/activerecord-testcase/frames]
5
+ * {Email}[mailto:ilia at nurey.com]
6
+
7
+ == Description
8
+
9
+ This gem extracts ActiveRecord::TestCase from Rails 4.2.0.
10
+ As of Rails 4.1 this class is private and no longer distributed as part of Rails.
11
+
12
+ == Features
13
+
14
+ == Examples
15
+
16
+ require 'active_record/test_case'
17
+
18
+ == Requirements
19
+
20
+ activesupport
21
+
22
+ == Install
23
+
24
+ $ gem install activerecord-testcase
25
+
26
+ == Copyright
27
+
28
+ Packaging of the gem:
29
+ Copyright (c) 2015 Ilia Lobsanov
30
+
31
+ See LICENSE.txt for details.
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+ require 'rubygems/tasks'
9
+
10
+ Gem::Tasks.new
11
+ rescue LoadError => e
12
+ warn e.message
13
+ warn "Run `gem install rubygems-tasks` to install Gem::Tasks."
14
+ end
15
+
16
+ begin
17
+ gem 'rdoc', '~> 3.0'
18
+ require 'rdoc/task'
19
+
20
+ RDoc::Task.new do |rdoc|
21
+ rdoc.title = "activerecord-testcase"
22
+ end
23
+ rescue LoadError => e
24
+ warn e.message
25
+ warn "Run `gem install rdoc` to install 'rdoc/task'."
26
+ end
27
+ task :doc => :rdoc
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = "activerecord-testcase"
5
+ gem.version = "0.1.0"
6
+ gem.summary = %q{ActiveRecord::TestCase extracted from Rails}
7
+ gem.description = %q{Defines test assertions to test against SQL queries}
8
+ gem.license = "MIT"
9
+ gem.authors = ["Ilia Lobsanov"]
10
+ gem.email = "ilia@nurey.com"
11
+ gem.homepage = "https://rubygems.org/gems/activerecord-testcase"
12
+
13
+ gem.files = `git ls-files`.split($/)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ['lib']
17
+
18
+ gem.add_dependency 'activesupport', '>= 4.2.0'
19
+
20
+ gem.add_development_dependency 'rdoc', '~> 3.0'
21
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
22
+ end
@@ -0,0 +1,123 @@
1
+ require 'active_support/test_case'
2
+
3
+ module ActiveRecord
4
+ # = Active Record Test Case
5
+ #
6
+ # Defines some test assertions to test against SQL queries.
7
+ class TestCase < ActiveSupport::TestCase #:nodoc:
8
+ def teardown
9
+ SQLCounter.clear_log
10
+ end
11
+
12
+ def assert_date_from_db(expected, actual, message = nil)
13
+ assert_equal expected.to_s, actual.to_s, message
14
+ end
15
+
16
+ def capture(stream)
17
+ stream = stream.to_s
18
+ captured_stream = Tempfile.new(stream)
19
+ stream_io = eval("$#{stream}")
20
+ origin_stream = stream_io.dup
21
+ stream_io.reopen(captured_stream)
22
+
23
+ yield
24
+
25
+ stream_io.rewind
26
+ return captured_stream.read
27
+ ensure
28
+ captured_stream.close
29
+ captured_stream.unlink
30
+ stream_io.reopen(origin_stream)
31
+ end
32
+
33
+ def capture_sql
34
+ SQLCounter.clear_log
35
+ yield
36
+ SQLCounter.log_all.dup
37
+ end
38
+
39
+ def assert_sql(*patterns_to_match)
40
+ capture_sql { yield }
41
+ ensure
42
+ failed_patterns = []
43
+ patterns_to_match.each do |pattern|
44
+ failed_patterns << pattern unless SQLCounter.log_all.any?{ |sql| pattern === sql }
45
+ end
46
+ assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map{ |p| p.inspect }.join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}"
47
+ end
48
+
49
+ def assert_queries(num = 1, options = {})
50
+ ignore_none = options.fetch(:ignore_none) { num == :any }
51
+ SQLCounter.clear_log
52
+ x = yield
53
+ the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
54
+ if num == :any
55
+ assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
56
+ else
57
+ mesg = "#{the_log.size} instead of #{num} queries were executed.#{the_log.size == 0 ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
58
+ assert_equal num, the_log.size, mesg
59
+ end
60
+ x
61
+ end
62
+
63
+ def assert_no_queries(options = {}, &block)
64
+ options.reverse_merge! ignore_none: true
65
+ assert_queries(0, options, &block)
66
+ end
67
+
68
+ def assert_column(model, column_name, msg=nil)
69
+ assert has_column?(model, column_name), msg
70
+ end
71
+
72
+ def assert_no_column(model, column_name, msg=nil)
73
+ assert_not has_column?(model, column_name), msg
74
+ end
75
+
76
+ def has_column?(model, column_name)
77
+ model.reset_column_information
78
+ model.column_names.include?(column_name.to_s)
79
+ end
80
+ end
81
+
82
+ class SQLCounter
83
+ class << self
84
+ attr_accessor :ignored_sql, :log, :log_all
85
+ def clear_log; self.log = []; self.log_all = []; end
86
+ end
87
+
88
+ self.clear_log
89
+
90
+ self.ignored_sql = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]
91
+
92
+ # FIXME: this needs to be refactored so specific database can add their own
93
+ # ignored SQL, or better yet, use a different notification for the queries
94
+ # instead examining the SQL content.
95
+ oracle_ignored = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im, /^\s*select .* from all_constraints/im, /^\s*select .* from all_tab_cols/im]
96
+ mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i, /^SHOW VARIABLES /]
97
+ postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select tablename\b.*from pg_tables\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
98
+ sqlite3_ignored = [/^\s*SELECT name\b.*\bFROM sqlite_master/im]
99
+
100
+ [oracle_ignored, mysql_ignored, postgresql_ignored, sqlite3_ignored].each do |db_ignored_sql|
101
+ ignored_sql.concat db_ignored_sql
102
+ end
103
+
104
+ attr_reader :ignore
105
+
106
+ def initialize(ignore = Regexp.union(self.class.ignored_sql))
107
+ @ignore = ignore
108
+ end
109
+
110
+ def call(name, start, finish, message_id, values)
111
+ sql = values[:sql]
112
+
113
+ # FIXME: this seems bad. we should probably have a better way to indicate
114
+ # the query was cached
115
+ return if 'CACHE' == values[:name]
116
+
117
+ self.class.log_all << sql
118
+ self.class.log << sql unless ignore =~ sql
119
+ end
120
+ end
121
+
122
+ ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
123
+ end
@@ -0,0 +1 @@
1
+ require 'active_record/test_case'
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-testcase
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ilia Lobsanov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rdoc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubygems-tasks
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
55
+ description: Defines test assertions to test against SQL queries
56
+ email: ilia@nurey.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".document"
62
+ - ".gitignore"
63
+ - ChangeLog.rdoc
64
+ - LICENSE.txt
65
+ - README.rdoc
66
+ - Rakefile
67
+ - activerecord-testcase.gemspec
68
+ - lib/active_record/test_case.rb
69
+ - lib/activerecord-testcase.rb
70
+ homepage: https://rubygems.org/gems/activerecord-testcase
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.2.2
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: ActiveRecord::TestCase extracted from Rails
94
+ test_files: []