axiom-do-adapter 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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gemtest +0 -0
- data/.gitignore +37 -0
- data/.rspec +4 -0
- data/.rvmrc +1 -0
- data/.travis.yml +35 -0
- data/CONTRIBUTING.md +11 -0
- data/Gemfile +10 -0
- data/Gemfile.devtools +57 -0
- data/Guardfile +23 -0
- data/LICENSE +20 -0
- data/README.md +26 -0
- data/Rakefile +5 -0
- data/TODO +0 -0
- data/axiom-do-adapter.gemspec +27 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +115 -0
- data/config/yardstick.yml +2 -0
- data/lib/axiom-do-adapter.rb +4 -0
- data/lib/axiom/adapter/data_objects.rb +55 -0
- data/lib/axiom/adapter/data_objects/statement.rb +109 -0
- data/lib/axiom/adapter/data_objects/version.rb +12 -0
- data/lib/axiom/relation/gateway.rb +374 -0
- data/spec/rcov.opts +7 -0
- data/spec/shared/binary_relation_method_behaviour.rb +51 -0
- data/spec/shared/unary_relation_method_behaviour.rb +21 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/config_alias.rb +3 -0
- data/spec/support/example_group_methods.rb +7 -0
- data/spec/support/ice_nine_config.rb +6 -0
- data/spec/unit/axiom/adapter/data_objects/class_methods/new_spec.rb +15 -0
- data/spec/unit/axiom/adapter/data_objects/read_spec.rb +66 -0
- data/spec/unit/axiom/adapter/data_objects/statement/class_methods/new_spec.rb +28 -0
- data/spec/unit/axiom/adapter/data_objects/statement/each_spec.rb +63 -0
- data/spec/unit/axiom/adapter/data_objects/statement/to_s_spec.rb +53 -0
- data/spec/unit/axiom/relation/gateway/class_methods/new_spec.rb +16 -0
- data/spec/unit/axiom/relation/gateway/difference_spec.rb +17 -0
- data/spec/unit/axiom/relation/gateway/drop_spec.rb +21 -0
- data/spec/unit/axiom/relation/gateway/each_spec.rb +86 -0
- data/spec/unit/axiom/relation/gateway/extend_spec.rb +29 -0
- data/spec/unit/axiom/relation/gateway/intersect_spec.rb +17 -0
- data/spec/unit/axiom/relation/gateway/join_spec.rb +44 -0
- data/spec/unit/axiom/relation/gateway/materialize_spec.rb +27 -0
- data/spec/unit/axiom/relation/gateway/optimize_spec.rb +23 -0
- data/spec/unit/axiom/relation/gateway/product_spec.rb +17 -0
- data/spec/unit/axiom/relation/gateway/project_spec.rb +21 -0
- data/spec/unit/axiom/relation/gateway/remove_spec.rb +21 -0
- data/spec/unit/axiom/relation/gateway/rename_spec.rb +21 -0
- data/spec/unit/axiom/relation/gateway/respond_to_spec.rb +29 -0
- data/spec/unit/axiom/relation/gateway/restrict_spec.rb +29 -0
- data/spec/unit/axiom/relation/gateway/reverse_spec.rb +21 -0
- data/spec/unit/axiom/relation/gateway/sort_by_spec.rb +29 -0
- data/spec/unit/axiom/relation/gateway/summarize_spec.rb +154 -0
- data/spec/unit/axiom/relation/gateway/take_spec.rb +21 -0
- data/spec/unit/axiom/relation/gateway/union_spec.rb +17 -0
- metadata +214 -0
data/spec/rcov.opts
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
shared_examples_for 'a binary relation method' do
|
4
|
+
describe 'when other has the same adapter' do
|
5
|
+
let(:other_relation) { mock('Other Relation') }
|
6
|
+
let(:other) { described_class.new(adapter, other_relation) }
|
7
|
+
let(:gateway) { mock('Other Gateway') }
|
8
|
+
|
9
|
+
before do
|
10
|
+
relation.stub!(operation).and_return(gateway)
|
11
|
+
end
|
12
|
+
|
13
|
+
it { should equal(gateway) }
|
14
|
+
|
15
|
+
it 'passes the other relation to the binary operation' do
|
16
|
+
relation.should_receive(operation).with(other_relation)
|
17
|
+
subject
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'when other has a different adapter' do
|
22
|
+
let(:other_adapter) { mock('Other Adapter') }
|
23
|
+
let(:other) { described_class.new(other_adapter, stub) }
|
24
|
+
|
25
|
+
before do
|
26
|
+
factory.stub!(:new).and_return(binary_relation)
|
27
|
+
end
|
28
|
+
|
29
|
+
it { should equal(binary_relation) }
|
30
|
+
|
31
|
+
it 'initializes the binary operation with the gateways' do
|
32
|
+
factory.should_receive(:new).with(object, other)
|
33
|
+
subject
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'when other has no adapter' do
|
38
|
+
let(:other) { mock('Other Relation') }
|
39
|
+
|
40
|
+
before do
|
41
|
+
factory.stub!(:new).and_return(binary_relation)
|
42
|
+
end
|
43
|
+
|
44
|
+
it { should equal(binary_relation) }
|
45
|
+
|
46
|
+
it 'initializes the binary operation with the gateway and other relation' do
|
47
|
+
factory.should_receive(:new).with(object, other)
|
48
|
+
subject
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
shared_examples_for 'a unary relation method' do
|
4
|
+
let(:gateway) { mock('New Gateway') }
|
5
|
+
|
6
|
+
before do
|
7
|
+
described_class.stub!(:new).and_return(gateway)
|
8
|
+
end
|
9
|
+
|
10
|
+
it { should equal(gateway) }
|
11
|
+
|
12
|
+
it 'tests the response is a relation' do
|
13
|
+
response.should_receive(:kind_of?).with(Relation)
|
14
|
+
subject
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'initializes the new gateway with the adapter and response' do
|
18
|
+
described_class.should_receive(:new).with(adapter, response)
|
19
|
+
subject
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'backports'
|
4
|
+
require 'backports/basic_object' unless defined?(::BasicObject)
|
5
|
+
require 'devtools/spec_helper'
|
6
|
+
require 'ice_nine'
|
7
|
+
|
8
|
+
if ENV['COVERAGE'] == 'true'
|
9
|
+
require 'simplecov'
|
10
|
+
require 'coveralls'
|
11
|
+
|
12
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
13
|
+
SimpleCov::Formatter::HTMLFormatter,
|
14
|
+
Coveralls::SimpleCov::Formatter
|
15
|
+
]
|
16
|
+
|
17
|
+
SimpleCov.start do
|
18
|
+
command_name 'spec:unit'
|
19
|
+
add_filter 'config'
|
20
|
+
add_filter 'spec'
|
21
|
+
minimum_coverage 100
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'axiom-do-adapter'
|
26
|
+
|
27
|
+
include Axiom
|
28
|
+
|
29
|
+
# require spec support files and shared behavior
|
30
|
+
Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
|
31
|
+
require file
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec.configure do |config|
|
35
|
+
config.extend Spec::ExampleGroupMethods
|
36
|
+
|
37
|
+
# Record the original Attribute descendants
|
38
|
+
config.before do
|
39
|
+
@original_descendants = Attribute.descendants.dup
|
40
|
+
end
|
41
|
+
|
42
|
+
# Reset the Attribute descendants
|
43
|
+
config.after do
|
44
|
+
Attribute.descendants.replace(@original_descendants)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/adapter/data_objects'
|
5
|
+
|
6
|
+
describe Adapter::DataObjects, '.new' do
|
7
|
+
subject { object.new(uri) }
|
8
|
+
|
9
|
+
let(:uri) { stub }
|
10
|
+
let(:object) { described_class }
|
11
|
+
|
12
|
+
it { should be_instance_of(described_class) }
|
13
|
+
|
14
|
+
it { should be_frozen }
|
15
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/adapter/data_objects'
|
5
|
+
|
6
|
+
describe Adapter::DataObjects, '#read' do
|
7
|
+
let(:uri) { stub }
|
8
|
+
let(:object) { described_class.new(uri) }
|
9
|
+
let(:relation) { mock('Relation') }
|
10
|
+
let(:statement) { mock('Statement') }
|
11
|
+
let(:rows) { [ [ 1 ], [ 2 ], [ 3 ] ] }
|
12
|
+
let(:yields) { [] }
|
13
|
+
|
14
|
+
before do
|
15
|
+
expectation = statement.stub(:each)
|
16
|
+
rows.each { |row| expectation.and_yield(row) }
|
17
|
+
|
18
|
+
described_class::Statement.stub!(:new).and_return(statement)
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a block' do
|
22
|
+
subject { object.read(relation) { |row| yields << row } }
|
23
|
+
|
24
|
+
let(:connection) { mock('Connection', :close => nil) }
|
25
|
+
|
26
|
+
before do
|
27
|
+
DataObjects::Connection.stub!(:new).and_return(connection)
|
28
|
+
end
|
29
|
+
|
30
|
+
it_should_behave_like 'a command method'
|
31
|
+
|
32
|
+
it 'opens a connection' do
|
33
|
+
DataObjects::Connection.should_receive(:new).with(uri).and_return(connection)
|
34
|
+
subject
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'closes a connection' do
|
38
|
+
connection.should_receive(:close).with(no_args)
|
39
|
+
subject
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does not close a connection if the constructor throws an exception' do
|
43
|
+
mock_exception = Class.new(Exception)
|
44
|
+
DataObjects::Connection.should_receive(:new).and_raise(mock_exception)
|
45
|
+
connection.should_not_receive(:close)
|
46
|
+
expect { subject }.to raise_error(mock_exception)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'yields each row' do
|
50
|
+
expect { subject }.to change { yields.dup }.
|
51
|
+
from([]).
|
52
|
+
to(rows)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'initializes a statement' do
|
56
|
+
described_class::Statement.should_receive(:new).with(connection, relation).and_return(statement)
|
57
|
+
subject
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'without a block' do
|
62
|
+
subject { object.read(relation) }
|
63
|
+
|
64
|
+
it { should be_instance_of(to_enum.class) }
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/adapter/data_objects/statement'
|
5
|
+
|
6
|
+
describe Adapter::DataObjects::Statement, '.new' do
|
7
|
+
let(:connection) { stub }
|
8
|
+
let(:relation) { stub }
|
9
|
+
let(:object) { described_class }
|
10
|
+
|
11
|
+
context 'without a visitor' do
|
12
|
+
subject { object.new(connection, relation) }
|
13
|
+
|
14
|
+
it { should be_instance_of(described_class) }
|
15
|
+
|
16
|
+
it { should be_frozen }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with a visitor' do
|
20
|
+
subject { object.new(connection, relation, visitor) }
|
21
|
+
|
22
|
+
let(:visitor) { stub }
|
23
|
+
|
24
|
+
it { should be_instance_of(described_class) }
|
25
|
+
|
26
|
+
it { should be_frozen }
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/adapter/data_objects/statement'
|
5
|
+
|
6
|
+
describe Adapter::DataObjects::Statement, '#each' do
|
7
|
+
let(:reader) { mock('Reader', :next! => false).as_null_object }
|
8
|
+
let(:command) { mock('Command', :execute_reader => reader).as_null_object }
|
9
|
+
let(:connection) { mock('Connection', :create_command => command) }
|
10
|
+
let(:attribute) { stub }
|
11
|
+
let(:primitive) { stub }
|
12
|
+
let(:relation) { mock('Relation', :header => [ attribute ]) }
|
13
|
+
let(:generator) { mock('Generator').as_null_object }
|
14
|
+
let(:rows) { [ stub, stub ] }
|
15
|
+
let(:object) { described_class.new(connection, relation, generator) }
|
16
|
+
let(:yields) { [] }
|
17
|
+
|
18
|
+
before do
|
19
|
+
command.stub!(:dup => command, :freeze => command)
|
20
|
+
attribute.stub_chain(:class, :primitive).and_return(primitive)
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with no block' do
|
24
|
+
subject { object.each }
|
25
|
+
|
26
|
+
it { should be_instance_of(to_enum.class) }
|
27
|
+
|
28
|
+
it 'yields the expected attributes' do
|
29
|
+
subject.to_a.should eql(object.to_a)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with a block' do
|
34
|
+
subject { object.each { |row| yields << row } }
|
35
|
+
|
36
|
+
before do
|
37
|
+
connection.should_receive(:create_command).with(object.to_s)
|
38
|
+
|
39
|
+
command.should_receive(:set_types).with([ primitive ]).ordered
|
40
|
+
command.should_receive(:execute_reader).with(no_args).ordered
|
41
|
+
|
42
|
+
rows.each do |values|
|
43
|
+
reader.should_receive(:next!).with(no_args).ordered.and_return(true)
|
44
|
+
reader.should_receive(:values).with(no_args).ordered.and_return(values)
|
45
|
+
end
|
46
|
+
|
47
|
+
reader.should_receive(:next!).with(no_args).ordered.and_return(false)
|
48
|
+
reader.should_receive(:close).with(no_args).ordered
|
49
|
+
end
|
50
|
+
|
51
|
+
before do
|
52
|
+
relation.should_receive(:header)
|
53
|
+
end
|
54
|
+
|
55
|
+
it_should_behave_like 'a command method'
|
56
|
+
|
57
|
+
it 'yields each row' do
|
58
|
+
expect { subject }.to change { yields.dup }.
|
59
|
+
from([]).
|
60
|
+
to(rows)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/adapter/data_objects/statement'
|
5
|
+
|
6
|
+
describe Adapter::DataObjects::Statement, '#to_s' do
|
7
|
+
subject { object.to_s }
|
8
|
+
|
9
|
+
let(:sql) { mock('SQL') }
|
10
|
+
let(:connection) { stub }
|
11
|
+
let(:relation) { mock('Relation') }
|
12
|
+
let(:generator) { mock('Generator', :to_sql => sql) }
|
13
|
+
|
14
|
+
context 'without a visitor' do
|
15
|
+
let(:visitor) { SQL::Generator::Relation } # default visitor
|
16
|
+
let(:object) { described_class.new(connection, relation) }
|
17
|
+
|
18
|
+
before do
|
19
|
+
visitor.stub!(:visit).and_return(generator)
|
20
|
+
end
|
21
|
+
|
22
|
+
it_should_behave_like 'an idempotent method'
|
23
|
+
|
24
|
+
it { should be_frozen }
|
25
|
+
|
26
|
+
it { should equal(sql) }
|
27
|
+
|
28
|
+
it 'visits the relation' do
|
29
|
+
visitor.should_receive(:visit).with(relation)
|
30
|
+
subject
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with a visitor' do
|
35
|
+
let(:visitor) { mock('Visitor', :visit => generator) }
|
36
|
+
let(:object) { described_class.new(connection, relation, visitor) }
|
37
|
+
|
38
|
+
before do
|
39
|
+
visitor.stub!(:visit).and_return(generator)
|
40
|
+
end
|
41
|
+
|
42
|
+
it_should_behave_like 'an idempotent method'
|
43
|
+
|
44
|
+
it { should be_frozen }
|
45
|
+
|
46
|
+
it { should equal(sql) }
|
47
|
+
|
48
|
+
it 'visits the relation' do
|
49
|
+
visitor.should_receive(:visit).with(relation)
|
50
|
+
subject
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/relation/gateway'
|
5
|
+
|
6
|
+
describe Relation::Gateway, '.new' do
|
7
|
+
subject { object.new(adapter, relation) }
|
8
|
+
|
9
|
+
let(:adapter) { stub }
|
10
|
+
let(:relation) { stub }
|
11
|
+
let(:object) { described_class }
|
12
|
+
|
13
|
+
it { should be_instance_of(described_class) }
|
14
|
+
|
15
|
+
it { should be_frozen }
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/relation/gateway'
|
5
|
+
|
6
|
+
describe Relation::Gateway, '#difference' do
|
7
|
+
subject { object.difference(other) }
|
8
|
+
|
9
|
+
let(:adapter) { mock('Adapter') }
|
10
|
+
let(:relation) { mock('Relation') }
|
11
|
+
let(:object) { described_class.new(adapter, relation) }
|
12
|
+
let(:operation) { :difference }
|
13
|
+
let(:factory) { Algebra::Difference }
|
14
|
+
let(:binary_relation) { mock(factory) }
|
15
|
+
|
16
|
+
it_should_behave_like 'a binary relation method'
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'axiom/relation/gateway'
|
5
|
+
|
6
|
+
describe Relation::Gateway, '#drop' do
|
7
|
+
subject { object.drop(args) }
|
8
|
+
|
9
|
+
let(:adapter) { mock('Adapter') }
|
10
|
+
let(:relation) { mock('Relation', :drop => response) }
|
11
|
+
let(:response) { mock('New Relation', :kind_of? => true) }
|
12
|
+
let!(:object) { described_class.new(adapter, relation) }
|
13
|
+
let(:args) { stub }
|
14
|
+
|
15
|
+
it_should_behave_like 'a unary relation method'
|
16
|
+
|
17
|
+
it 'forwards the arguments to relation#drop' do
|
18
|
+
relation.should_receive(:drop).with(args)
|
19
|
+
subject
|
20
|
+
end
|
21
|
+
end
|