sunstone 6.1.0.2 → 7.0.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/ext/active_record/associations/collection_association.rb +1 -1
  3. data/ext/active_record/attribute_methods.rb +7 -1
  4. data/ext/active_record/finder_methods.rb +14 -13
  5. data/ext/active_record/persistence.rb +6 -3
  6. data/ext/active_record/relation/calculations.rb +11 -4
  7. data/ext/active_record/relation/query_methods.rb +1 -1
  8. data/ext/active_record/statement_cache.rb +0 -1
  9. data/ext/arel/nodes/select_statement.rb +3 -3
  10. data/lib/active_record/connection_adapters/sunstone/column.rb +1 -1
  11. data/lib/active_record/connection_adapters/sunstone/database_statements.rb +8 -9
  12. data/lib/active_record/connection_adapters/sunstone/schema_statements.rb +31 -14
  13. data/lib/active_record/connection_adapters/sunstone_adapter.rb +17 -7
  14. data/lib/arel/collectors/sunstone.rb +25 -4
  15. data/lib/arel/visitors/sunstone.rb +21 -26
  16. data/lib/sunstone/connection.rb +40 -13
  17. data/lib/sunstone/version.rb +1 -1
  18. metadata +21 -61
  19. data/.github/workflows/main.yml +0 -141
  20. data/.gitignore +0 -31
  21. data/.tm_properties +0 -1
  22. data/Gemfile +0 -4
  23. data/README.md +0 -46
  24. data/Rakefile +0 -37
  25. data/TODO.md +0 -89
  26. data/sunstone.gemspec +0 -40
  27. data/test/active_record/associations/belongs_to_test.rb +0 -162
  28. data/test/active_record/associations/has_and_belongs_to_many_test.rb +0 -125
  29. data/test/active_record/associations/has_many_test.rb +0 -244
  30. data/test/active_record/eager_loading_test.rb +0 -62
  31. data/test/active_record/persistance_test.rb +0 -184
  32. data/test/active_record/preload_test.rb +0 -51
  33. data/test/active_record/query/all_test.rb +0 -33
  34. data/test/active_record/query/count_test.rb +0 -51
  35. data/test/active_record/query/distinct_test.rb +0 -30
  36. data/test/active_record/query/find_test.rb +0 -37
  37. data/test/active_record/query/limit_test.rb +0 -19
  38. data/test/active_record/query/order_test.rb +0 -27
  39. data/test/active_record/query/where_test.rb +0 -79
  40. data/test/active_record/query_test.rb +0 -131
  41. data/test/active_record/rpc_test.rb +0 -30
  42. data/test/schema_mock.rb +0 -121
  43. data/test/sunstone/connection/column_definition_test.rb +0 -30
  44. data/test/sunstone/connection/configuration_test.rb +0 -44
  45. data/test/sunstone/connection/cookie_store_test.rb +0 -37
  46. data/test/sunstone/connection/request_helper_test.rb +0 -105
  47. data/test/sunstone/connection/send_request_test.rb +0 -164
  48. data/test/sunstone/connection_test.rb +0 -23
  49. data/test/test_helper.rb +0 -153
@@ -1,105 +0,0 @@
1
- require 'test_helper'
2
-
3
- class Sunstone::Connection::RequestHelpersTest < ActiveSupport::TestCase
4
-
5
- # Sunstone.get ==============================================================
6
-
7
- test '#get(path)' do
8
- connection = Sunstone::Connection.new(url: "http://testhost.com")
9
- stub_request(:get, "http://testhost.com/test").to_return(:body => "get")
10
-
11
- assert_equal('get', connection.get('/test').body)
12
- end
13
-
14
- test '#get(path, params) with params as string' do
15
- connection = Sunstone::Connection.new(url: "http://testhost.com")
16
- stub_request(:get, "http://testhost.com/test").with(:query => {'key' => 'value'}).to_return(:body => "get")
17
-
18
- assert_equal 'get', connection.get('/test', 'key=value').body
19
- end
20
-
21
- test '#get(path, params) with params as hash' do
22
- connection = Sunstone::Connection.new(url: "http://testhost.com")
23
- stub_request(:get, "http://testhost.com/test").with(:query => {'key' => 'value'}).to_return(:body => "get")
24
-
25
- assert_equal 'get', connection.get('/test', {:key => 'value'}).body
26
- end
27
-
28
- test '#get(path, &block)' do
29
- connection = Sunstone::Connection.new(url: "http://testhost.com")
30
- stub_request(:get, "http://testhost.com/test").to_return(:body => 'get')
31
-
32
- connection.get('/test') do |response|
33
- assert_equal 'get', response.body
34
- end
35
- end
36
-
37
- # Sunstone.post =============================================================
38
-
39
- test '#post(path)' do
40
- connection = Sunstone::Connection.new(url: "http://testhost.com")
41
- stub_request(:post, "http://testhost.com/test").to_return(:body => "post")
42
-
43
- assert_equal('post', connection.post('/test').body)
44
- end
45
-
46
- test '#post(path, body)' do
47
- connection = Sunstone::Connection.new(url: "http://testhost.com")
48
- stub_request(:post, "http://testhost.com/test").with(:body => 'body').to_return(:body => "post")
49
-
50
- assert_equal('post', connection.post('/test', 'body').body)
51
- end
52
-
53
- test '#post(path, &block)' do
54
- connection = Sunstone::Connection.new(url: "http://testhost.com")
55
- stub_request(:post, "http://testhost.com/test").to_return(:body => 'post')
56
-
57
- connection.post('/test') do |response|
58
- assert_equal 'post', response.body
59
- end
60
- end
61
-
62
- # Sunstone.put ==============================================================
63
-
64
- test '#put(path)' do
65
- connection = Sunstone::Connection.new(url: "http://testhost.com")
66
- stub_request(:put, "http://testhost.com/test").to_return(:body => "put")
67
-
68
- assert_equal('put', connection.put('/test').body)
69
- end
70
-
71
- test '#put(path, body)' do
72
- connection = Sunstone::Connection.new(url: "http://testhost.com")
73
- stub_request(:put, "http://testhost.com/test").with(:body => 'body').to_return(:body => "put")
74
-
75
- assert_equal('put', connection.put('/test', 'body').body)
76
- end
77
-
78
- test '#put(path, &block)' do
79
- connection = Sunstone::Connection.new(url: "http://testhost.com")
80
- stub_request(:put, "http://testhost.com/test").to_return(:body => 'put')
81
-
82
- connection.put('/test') do |response|
83
- assert_equal 'put', response.body
84
- end
85
- end
86
-
87
- # Sunstone.delete ===========================================================
88
-
89
- test '#delete' do
90
- connection = Sunstone::Connection.new(url: "http://testhost.com")
91
- stub_request(:delete, "http://testhost.com/test").to_return(:body => "delete")
92
-
93
- assert_equal('delete', connection.delete('/test').body)
94
- end
95
-
96
- test '#delete(path, &block)' do
97
- connection = Sunstone::Connection.new(url: "http://testhost.com")
98
- stub_request(:delete, "http://testhost.com/test").to_return(:body => 'delete')
99
-
100
- connection.delete('/test') do |response|
101
- assert_equal 'delete', response.body
102
- end
103
- end
104
-
105
- end
@@ -1,164 +0,0 @@
1
- require 'test_helper'
2
-
3
- class Sunstone::Connection::SendRequestTest < ActiveSupport::TestCase
4
-
5
- test '#send_request(#<Net::HTTPRequest>) includes the api-key header when present' do
6
- connection = Sunstone::Connection.new(url: "http://my_api_key@example.com")
7
-
8
- test_stub = stub_request(:get, "http://example.com/verify").with { |req|
9
- req.headers['Api-Key'] == 'my_api_key'
10
- }
11
- connection.get('/verify')
12
- assert_requested(test_stub)
13
- end
14
-
15
- test '#send_request(#<Net::HTTPRequest>) includes the user_agent' do
16
- connection = Sunstone::Connection.new(url: "http://example.com")
17
-
18
- test_stub = stub_request(:get, "http://example.com/verify").with { |req|
19
- req.headers['User-Agent'] =~ /Sunstone\/\S+ Ruby\/\S+ \S+/
20
- }
21
- connection.get('/verify')
22
- assert_requested(test_stub)
23
-
24
- # Custom Agent
25
- connection = Sunstone::Connection.new(url: "http://example.com", user_agent: "MyClient/2")
26
-
27
- test_stub = stub_request(:get, "http://example.com/verify").with { |req|
28
- req.headers['User-Agent'] =~ /MyClient\/2 Sunstone\/\S+ Ruby\/\S+ \S+/
29
- }
30
- connection.get('/verify')
31
- assert_requested(test_stub)
32
- end
33
-
34
- test '#send_request(#<Net::HTTPRequest>)' do
35
- stub_request(:get, "http://testhost.com/test").to_return(body: 'get')
36
-
37
- connection = Sunstone::Connection.new(url: "http://testhost.com")
38
- assert_equal('get', connection.send_request(Net::HTTP::Get.new('/test')).body)
39
- end
40
-
41
- test '#send_request(#<Net::HTTPRequest>, body) with string body' do
42
- stub_request(:post, "http://testhost.com/test").with(
43
- body: '{"key":"value"}'
44
- ).to_return(
45
- body: "post"
46
- )
47
-
48
- connection = Sunstone::Connection.new(url: "http://testhost.com")
49
- assert_equal('post', connection.send_request(Net::HTTP::Post.new('/test'), '{"key":"value"}').body)
50
- end
51
-
52
- test '#send_request(#<Net::HTTPRequest>, body) with IO body' do
53
- stub_request(:post, "http://testhost.com/test").with { |request|
54
- request.headers['Transfer-Encoding'] == "chunked" && request.body == '{"key":"value"}'
55
- }.to_return(:body => "post")
56
-
57
- rd, wr = IO.pipe
58
- wr.write('{"key":"value"}')
59
- wr.close
60
-
61
- connection = Sunstone::Connection.new(url: "http://testhost.com")
62
- assert_equal('post', connection.send_request(Net::HTTP::Post.new('/test'), rd).body)
63
- end
64
-
65
- test '#send_request(#<Net::HTTPRequest>, body) with Ruby Object body' do
66
- stub_request(:post, "http://testhost.com/test").with(body: '{"key":"value"}').to_return(body: "post")
67
-
68
- connection = Sunstone::Connection.new(url: "http://testhost.com")
69
- assert_equal('post', connection.send_request(Net::HTTP::Post.new('/test'), {:key => 'value'}).body)
70
- end
71
-
72
- test '#send_request(#<Net::HTTPRequest>) raises Sunstone::Exceptions on non-200 responses' do
73
- stub_request(:get, "http://testhost.com/400").to_return(status: 400)
74
- stub_request(:get, "http://testhost.com/401").to_return(status: 401)
75
- stub_request(:get, "http://testhost.com/403").to_return(status: 403)
76
- stub_request(:get, "http://testhost.com/404").to_return(status: 404)
77
- stub_request(:get, "http://testhost.com/410").to_return(status: 410)
78
- stub_request(:get, "http://testhost.com/422").to_return(status: 422)
79
- stub_request(:get, "http://testhost.com/450").to_return(status: 450)
80
- stub_request(:get, "http://testhost.com/503").to_return(status: 503)
81
- stub_request(:get, "http://testhost.com/550").to_return(status: 550)
82
-
83
- connection = Sunstone::Connection.new(url: "http://testhost.com")
84
- assert_raises(Sunstone::Exception::BadRequest) { connection.send_request(Net::HTTP::Get.new('/400')) }
85
- assert_raises(Sunstone::Exception::Unauthorized) { connection.send_request(Net::HTTP::Get.new('/401')) }
86
- assert_raises(Sunstone::Exception::Forbidden) { connection.send_request(Net::HTTP::Get.new('/403')) }
87
- assert_raises(Sunstone::Exception::NotFound) { connection.send_request(Net::HTTP::Get.new('/404')) }
88
- assert_raises(Sunstone::Exception::Gone) { connection.send_request(Net::HTTP::Get.new('/410')) }
89
- assert_raises(Sunstone::Exception::ApiVersionUnsupported) { connection.send_request(Net::HTTP::Get.new('/422')) }
90
- assert_raises(Sunstone::Exception) { connection.send_request(Net::HTTP::Get.new('/450')) }
91
- assert_raises(Sunstone::Exception::ServiceUnavailable) { connection.send_request(Net::HTTP::Get.new('/503')) }
92
- assert_raises(Sunstone::ServerError) { connection.send_request(Net::HTTP::Get.new('/550')) }
93
- end
94
-
95
- test '#send_request(#<Net::HTTPRequest>, &block) returns value returned from &block' do
96
- stub_request(:get, "http://testhost.com/test").to_return(body: 'get')
97
-
98
- connection = Sunstone::Connection.new(url: "http://testhost.com")
99
- value = connection.send_request(Net::HTTP::Get.new('/test')) do |response|
100
- 3215
101
- end
102
-
103
- assert_equal 3215, value
104
- end
105
-
106
- test '#send_request(#<Net::HTTPRequest>, &block)' do
107
- connection = Sunstone::Connection.new(url: "http://testhost.com")
108
- stub_request(:get, "http://testhost.com/test").to_return(body: 'get')
109
-
110
- connection.send_request(Net::HTTP::Get.new('/test')) do |response|
111
- assert_equal 'get', response.body
112
- end
113
-
114
- # make sure block is not called when not in valid_response_codes
115
- stub_request(:get, "http://testhost.com/test").to_return(status: 401, body: 'get')
116
-
117
- assert_raises(Sunstone::Exception::Unauthorized) {
118
- connection.send_request(Net::HTTP::Get.new('/test')) do |response|
119
- raise Sunstone::Exception, 'Should not get here'
120
- end
121
- }
122
- end
123
-
124
- test '#send_request(#<Net::HTTPRequest>, &block) with block reading chunks' do
125
- connection = Sunstone::Connection.new(url: "http://testhost.com")
126
-
127
- rd, wr = IO.pipe
128
- rd = Net::BufferedIO.new(rd)
129
- wr.write(<<-DATA.gsub(/^ +/, '').gsub(/\n/, "\r\n"))
130
- HTTP/1.1 200 OK
131
- Content-Length: 5
132
-
133
- hello
134
- DATA
135
-
136
- res = Net::HTTPResponse.read_new(rd)
137
- mock_connection = mock('connection')
138
- mock_connection.stubs(:request).yields(res)
139
- connection.instance_variable_set(:@connection, mock_connection)
140
-
141
- res.reading_body(rd, true) do
142
- connection.send_request(Net::HTTP::Get.new('/test')) do |response|
143
- response.read_body do |chunk|
144
- assert_equal('hello', chunk)
145
- end
146
- end
147
- end
148
- end
149
-
150
- # TODO: support multple depreaction-notice headers
151
- test 'deprecation warning printed when deprecation header returned' do
152
- connection = Sunstone::Connection.new(url: "http://testhost.com")
153
-
154
- stub_request(:get, "http://testhost.com/test").to_return(
155
- body: 'get',
156
- headers: { 'Deprecation-Notice': 'my deprecation message' }
157
- )
158
-
159
- ActiveSupport::Deprecation.expects(:warn).with('my deprecation message')
160
-
161
- connection.send_request(Net::HTTP::Get.new('/test'))
162
- end
163
-
164
- end
@@ -1,23 +0,0 @@
1
- require 'test_helper'
2
-
3
- class Sunstone::ConnectionTest < ActiveSupport::TestCase
4
-
5
- # #ping =====================================================================
6
-
7
- test '#ping' do
8
- connection = Sunstone::Connection.new(url: "http://testhost.com")
9
- stub_request(:get, "http://testhost.com/ping").to_return(:body => 'pong')
10
-
11
- assert_equal( 'pong', connection.ping )
12
- end
13
-
14
- # #server_config ===========================================================
15
-
16
- test '#config' do
17
- connection = Sunstone::Connection.new(url: "http://testhost.com")
18
- stub_request(:get, "http://testhost.com/config").to_return(:body => '{"server": "configs"}')
19
-
20
- assert_equal( {:server => "configs"}, connection.server_config )
21
- end
22
-
23
- end
data/test/test_helper.rb DELETED
@@ -1,153 +0,0 @@
1
- # To make testing/debugging easier, test within this source tree versus an
2
- # installed gem
3
- $LOAD_PATH << File.expand_path('../lib', __FILE__)
4
-
5
- require 'simplecov'
6
- SimpleCov.start do
7
- add_group 'lib', 'sunstone/lib'
8
- add_group 'ext', 'sunstone/ext'
9
- end
10
-
11
- require 'rgeo'
12
- require 'byebug'
13
- require "minitest/autorun"
14
- require 'minitest/unit'
15
- require 'minitest/reporters'
16
- require 'webmock/minitest'
17
- require 'mocha/minitest'
18
-
19
- require 'sunstone'
20
- require File.expand_path('../schema_mock.rb', __FILE__)
21
-
22
- Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
23
-
24
- $debugging = false
25
-
26
- # File 'lib/active_support/testing/declarative.rb', somewhere in rails....
27
- class ActiveSupport::TestCase
28
- include WebMock::API
29
-
30
- # File 'lib/active_support/testing/declarative.rb'
31
- def self.test(name, &block)
32
- test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
33
- defined = method_defined? test_name
34
- raise "#{test_name} is already defined in #{self}" if defined
35
- if block_given?
36
- define_method(test_name, &block)
37
- else
38
- define_method(test_name) do
39
- skip "No implementation provided for #{name}"
40
- end
41
- end
42
- end
43
-
44
- def pack(data)
45
-
46
- end
47
-
48
- def unpack(data)
49
- MessagePack.unpack(CGI::unescape(data))
50
- end
51
-
52
- def deep_transform_query(object)
53
- case object
54
- when Hash
55
- object.each_with_object({}) do |(key, value), result|
56
- result[key.to_s] = deep_transform_query(value)
57
- end
58
- when Array
59
- object.map {|e| deep_transform_query(e) }
60
- when Symbol
61
- object.to_s
62
- else
63
- object
64
- end
65
- end
66
-
67
- def webmock(method, path, query=nil)
68
- query = deep_transform_query(query) if query
69
-
70
- stub_request(method, /^#{ActiveRecord::Base.connection.instance_variable_get(:@connection).url}/).with do |req|
71
- if query
72
- puts unpack(req&.uri&.query&.sub(/=true$/, '')) if req&.uri&.query
73
- req&.uri&.path == path && req.uri.query && unpack(req.uri.query.sub(/=true$/, '')) == query
74
- else
75
- req&.uri&.path == path && req.uri.query.nil?
76
- end
77
- end
78
- end
79
-
80
- def debug
81
- ActiveRecord::Base.logger = Logger.new(STDOUT)
82
- $debugging = true
83
- yield
84
- ensure
85
- ActiveRecord::Base.logger = nil
86
- $debugging = false
87
- end
88
-
89
-
90
- class SQLLogger
91
- class << self
92
- attr_accessor :ignored_sql, :log, :log_all
93
- def clear_log; self.log = []; self.log_all = []; end
94
- end
95
-
96
- self.clear_log
97
-
98
- self.ignored_sql = [/^PRAGMA/i, /^SELECT currval/i, /^SELECT CAST/i, /^SELECT @@IDENTITY/i, /^SELECT @@ROWCOUNT/i, /^SAVEPOINT/i, /^ROLLBACK TO SAVEPOINT/i, /^RELEASE SAVEPOINT/i, /^SHOW max_identifier_length/i, /^BEGIN/i, /^COMMIT/i]
99
-
100
- # FIXME: this needs to be refactored so specific database can add their own
101
- # ignored SQL, or better yet, use a different notification for the queries
102
- # instead examining the SQL content.
103
- 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]
104
- mysql_ignored = [/^SHOW FULL TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i, /^SHOW VARIABLES /, /^\s*SELECT (?:column_name|table_name)\b.*\bFROM information_schema\.(?:key_column_usage|tables)\b/im]
105
- 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]
106
- sqlite3_ignored = [/^\s*SELECT name\b.*\bFROM sqlite_master/im, /^\s*SELECT sql\b.*\bFROM sqlite_master/im]
107
-
108
- [oracle_ignored, mysql_ignored, postgresql_ignored, sqlite3_ignored].each do |db_ignored_sql|
109
- ignored_sql.concat db_ignored_sql
110
- end
111
-
112
- attr_reader :ignore
113
-
114
- def initialize(ignore = Regexp.union(self.class.ignored_sql))
115
- @ignore = ignore
116
- end
117
-
118
- def call(name, start, finish, message_id, values)
119
- sql = values[:sql]
120
-
121
- # FIXME: this seems bad. we should probably have a better way to indicate
122
- # the query was cached
123
- return if 'CACHE' == values[:name]
124
-
125
- self.class.log_all << sql
126
- unless ignore =~ sql
127
- if $debugging
128
- puts caller.select { |l| l.starts_with?(File.expand_path('../../lib', __FILE__)) }
129
- puts "\n\n"
130
- end
131
- end
132
- self.class.log << sql unless ignore =~ sql
133
- end
134
- end
135
- ActiveSupport::Notifications.subscribe('sql.active_record', SQLLogger.new)
136
-
137
- # test/unit backwards compatibility methods
138
- alias :assert_raise :assert_raises
139
- alias :assert_not_empty :refute_empty
140
- alias :assert_not_equal :refute_equal
141
- alias :assert_not_in_delta :refute_in_delta
142
- alias :assert_not_in_epsilon :refute_in_epsilon
143
- alias :assert_not_includes :refute_includes
144
- alias :assert_not_instance_of :refute_instance_of
145
- alias :assert_not_kind_of :refute_kind_of
146
- alias :assert_no_match :refute_match
147
- alias :assert_not_nil :refute_nil
148
- alias :assert_not_operator :refute_operator
149
- alias :assert_not_predicate :refute_predicate
150
- alias :assert_not_respond_to :refute_respond_to
151
- alias :assert_not_same :refute_same
152
-
153
- end