sql_matchers 0.0.1

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
+ SHA256:
3
+ metadata.gz: 4f1773fdab03f1f4a89f6b58bcdaeb0833ab5666836cd7536acd4627f65e9618
4
+ data.tar.gz: ba267a8def94f0e7579e9d0be92dead4504ec0c2a8f02f5d92cc3991adf9f840
5
+ SHA512:
6
+ metadata.gz: adf3277acce82bff99919c98242e3aa8dd83145fd3db5349bfc3ee34e07bb1fae2815cb68f0edc33342b0758a64a2d346ede745a21f7f97e1f1e4241e0c16365
7
+ data.tar.gz: 35980c31136c6b60c3f462376fc502f752dbf692de108ce38cde0ef9f3d8e56d5618caaad54f861a7b026403784a5a6820d0531f5ad3afb06c815f7fa0e382e0
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,33 @@
1
+ ## Security issues
2
+
3
+ If you have found a security related issue, please do not file an issue on
4
+ GitHub or send a PR addressing the issue. Contact [Keygen](mailto:security@keygen.sh)
5
+ directly. You will be given public credit for your disclosure.
6
+
7
+ ## Reporting issues
8
+
9
+ Please try to answer the following questions in your bug report:
10
+
11
+ - What did you do?
12
+ - What did you expect to happen?
13
+ - What happened instead?
14
+
15
+ Make sure to include as much relevant information as possible. Ruby version,
16
+ Rails version, `sql_matchers` version, OS version and any stack traces
17
+ you have are very valuable.
18
+
19
+ ## Pull Requests
20
+
21
+ - **Add tests!** Your patch won't be accepted if it doesn't have tests.
22
+
23
+ - **Document any change in behaviour**. Make sure the README and any other
24
+ relevant documentation are kept up-to-date.
25
+
26
+ - **Create topic branches**. Please don't ask us to pull from your master branch.
27
+
28
+ - **One pull request per feature**. If you want to do more than one thing, send
29
+ multiple pull requests.
30
+
31
+ - **Send coherent history**. Make sure each individual commit in your pull
32
+ request is meaningful. If you had to make multiple intermediate commits while
33
+ developing, please squash them before sending them to us.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2024 Keygen LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # sql_matchers
2
+
3
+ [![CI](https://github.com/keygen-sh/sql_matchers/actions/workflows/test.yml/badge.svg)](https://github.com/keygen-sh/sql_matchers/actions)
4
+ [![Gem Version](https://badge.fury.io/rb/sql_matchers.svg)](https://badge.fury.io/rb/sql_matchers)
5
+
6
+ Use `sql_matchers` to create temporary tables and models in RSpec specs,
7
+ rather than create and maintain a dummy Rails application or messy block-level
8
+ constants.
9
+
10
+ This gem was extracted from [Keygen](https://keygen.sh).
11
+
12
+ Sponsored by:
13
+
14
+ <a href="https://keygen.sh?ref=sql_matchers">
15
+ <div>
16
+ <img src="https://keygen.sh/images/logo-pill.png" width="200" alt="Keygen">
17
+ </div>
18
+ </a>
19
+
20
+ _A fair source software licensing and distribution API._
21
+
22
+ ## Installation
23
+
24
+ Add this line to your application's `Gemfile`:
25
+
26
+ ```ruby
27
+ gem 'sql_matchers'
28
+ ```
29
+
30
+ And then execute:
31
+
32
+ ```bash
33
+ $ bundle
34
+ ```
35
+
36
+ Or install it yourself as:
37
+
38
+ ```bash
39
+ $ gem install sql_matchers
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ ### `temporary_table`
45
+
46
+ To define a temporary table:
47
+
48
+ ```ruby
49
+ describe Example do
50
+ temporary_table :user do |t|
51
+ t.string :email
52
+ t.string :first_name
53
+ t.string :last_name
54
+ t.index :email, unique: true
55
+ end
56
+
57
+ it 'should define a table' do
58
+ expect(ActiveRecord::Base.connection.table_exists?(:user)).to be true
59
+ end
60
+ end
61
+ ```
62
+
63
+ The full Active Record schema API is available.
64
+
65
+ ### `temporary_model`
66
+
67
+ To define an Active Record:
68
+
69
+ ```ruby
70
+ describe Example do
71
+ temporary_model :user do
72
+ has_many :posts
73
+ end
74
+
75
+ it 'should define a record' do
76
+ expect(const_defined?(:User)).to be true
77
+ end
78
+ end
79
+ ```
80
+
81
+ To define an Active Model:
82
+
83
+ ```ruby
84
+ describe Example do
85
+ temporary_model :guest_user, table_name: nil, base_class: nil do
86
+ include ActiveModel::Model
87
+ end
88
+
89
+ it 'should define a model' do
90
+ expect(const_defined?(:GuestUser)).to be true
91
+ end
92
+ end
93
+ ```
94
+
95
+ To define a PORO:
96
+
97
+ ```ruby
98
+ describe Example do
99
+ temporary_model :null_user, table_name: nil, base_class: nil do
100
+ # ...
101
+ end
102
+
103
+ it 'should define a PORO' do
104
+ expect(const_defined?(:NullUser)).to be true
105
+ end
106
+ end
107
+ ```
108
+
109
+ ## Future
110
+
111
+ Right now, the gem only supports RSpec, but we're open to pull requests that
112
+ extend the functionality to other testing frameworks.
113
+
114
+ ## Supported Rubies
115
+
116
+ **`sql_matchers` supports Ruby 3.1 and above.** We encourage you to upgrade
117
+ if you're on an older version. Ruby 3 provides a lot of great features, like
118
+ better pattern matching and a new shorthand hash syntax.
119
+
120
+ ## Is it any good?
121
+
122
+ Yes.
123
+
124
+ ## Contributing
125
+
126
+ If you have an idea, or have discovered a bug, please open an issue or create a
127
+ pull request.
128
+
129
+ ## License
130
+
131
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/SECURITY.md ADDED
@@ -0,0 +1,8 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a vulnerability
4
+
5
+ If you find a vulnerability in `sql_matchers`, please contact Keygen via
6
+ [email](mailto:security@keygen.sh).
7
+
8
+ You will be given public credit for your disclosure.
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SqlMatchers
4
+ module Loggers
5
+ class Query
6
+ IGNORED_STATEMENTS = %w[CACHE SCHEMA]
7
+ IGNORED_STATEMENT_RE = %r{^(?:ROLLBACK|BEGIN|COMMIT|SAVEPOINT|RELEASE)}
8
+ IGNORED_COMMENT_RE = %r{
9
+ /\*(\w+='\w+',?)+\*/ # query log tags
10
+ }x
11
+
12
+ def initialize
13
+ @queries = []
14
+ end
15
+
16
+ def self.subscribe(&) = new.subscribe(&)
17
+ def subscribe(&block)
18
+ ActiveSupport::Notifications.subscribed(
19
+ logger_proc,
20
+ 'sql.active_record',
21
+ &proc {
22
+ result = block.call
23
+ result.load if result in ActiveRecord::Relation # autoload relations
24
+ }
25
+ )
26
+
27
+ @queries
28
+ end
29
+
30
+ private
31
+
32
+ def logger_proc = proc(&method(:logger))
33
+ def logger(event)
34
+ unless IGNORED_STATEMENTS.include?(event.payload[:name]) || IGNORED_STATEMENT_RE.match(event.payload[:sql])
35
+ query = event.payload[:sql].gsub(IGNORED_COMMENT_RE, '')
36
+ .squish
37
+
38
+ @queries << query
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SqlMatchers
4
+ module Loggers; end
5
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../loggers/query'
4
+
5
+ module SqlMatchers
6
+ module Matchers
7
+ class Query
8
+ def initialize(count: nil, &block)
9
+ @count = count
10
+ @block = block
11
+ end
12
+
13
+ def supports_block_expectations? = true
14
+ def supports_value_expectations? = true
15
+
16
+ def matches?(block)
17
+ @queries = Loggers::Query.subscribe(&block)
18
+
19
+ (@count.nil? || @queries.size == @count) && (
20
+ @block.nil? || @block.call(@queries)
21
+ )
22
+ end
23
+
24
+ def failure_message
25
+ "expected to match #{@count} queries but got #{@queries.size}"
26
+ end
27
+
28
+ def failure_message_when_negated
29
+ "expected to not match #{@count} queries"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'anbt-sql-formatter/formatter'
4
+
5
+ module SqlMatchers
6
+ module Matchers
7
+ class Sql
8
+ attr_reader :actual, :expected
9
+
10
+ def initialize(expected)
11
+ @expected = expected
12
+ @formatter = AnbtSql::Formatter.new(
13
+ AnbtSql::Rule.new.tap do |r|
14
+ r.keyword = AnbtSql::Rule::KEYWORD_UPPER_CASE
15
+ r.function_names += %w[count sum substr date]
16
+ r.indent_string = ' '
17
+ end
18
+ )
19
+ end
20
+
21
+ def diffable? = true
22
+ def matches?(actual)
23
+ @expected = formatter.format(+expected.to_s.strip)
24
+ @actual = formatter.format(+actual.to_s.strip)
25
+
26
+ @actual == @expected
27
+ end
28
+
29
+ def failure_message
30
+ <<~MSG
31
+ Expected SQL to match:
32
+ expected:
33
+ #{@expected.squish}
34
+ got:
35
+ #{@actual.squish}
36
+ MSG
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :formatter
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'matchers/query'
4
+ require_relative 'matchers/sql'
5
+
6
+ module SqlMatchers
7
+ module Matchers
8
+ def match_query(...) = Query.new(...)
9
+ def match_queries(...) = match_query(...)
10
+ def match_sql(...) = Sql.new(...)
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'matchers'
4
+
5
+ module SqlMatchers
6
+ module Methods
7
+ include Matchers
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SqlMatchers
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
4
+
5
+ require_relative 'sql_matchers/methods'
6
+ require_relative 'sql_matchers/version'
7
+
8
+ module SqlMatchers; end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sql_matchers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Zeke Gabrielse
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-08-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: anbt-sql-formatter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: temporary_tables
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.0.pre.rc.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0.pre.rc.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.4'
69
+ description: Query and SQL matchers for RSpec.
70
+ email:
71
+ - oss@keygen.sh
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - CHANGELOG.md
77
+ - CONTRIBUTING.md
78
+ - LICENSE
79
+ - README.md
80
+ - SECURITY.md
81
+ - lib/sql_matchers.rb
82
+ - lib/sql_matchers/loggers.rb
83
+ - lib/sql_matchers/loggers/query.rb
84
+ - lib/sql_matchers/matchers.rb
85
+ - lib/sql_matchers/matchers/query.rb
86
+ - lib/sql_matchers/matchers/sql.rb
87
+ - lib/sql_matchers/methods.rb
88
+ - lib/sql_matchers/version.rb
89
+ homepage: https://github.com/keygen-sh/sql_matchers
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '3.1'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.4.13
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Query and SQL matchers for RSpec.
112
+ test_files: []