kangaroo 0.0.3 → 0.1.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -1
- data/Gemfile +11 -0
- data/README.md +23 -132
- data/Rakefile +0 -8
- data/bin/kang +5 -64
- data/bin/kangdoc +21 -0
- data/bin/kangviz +21 -0
- data/config/kangaroo.yml.sample +12 -2
- data/docs/Architecture.md +1 -0
- data/docs/Classes.md +67 -0
- data/docs/Installation.md +2 -1
- data/docs/Usage.md +1 -0
- data/kangaroo.gemspec +8 -8
- data/lib/kangaroo.rb +3 -2
- data/lib/kangaroo/commands/base.rb +123 -0
- data/lib/kangaroo/commands/cli.rb +65 -0
- data/lib/kangaroo/commands/doc.rb +44 -0
- data/lib/kangaroo/commands/endpoint.rb +33 -0
- data/lib/kangaroo/commands/viz.rb +58 -0
- data/lib/kangaroo/doc.rb +2 -0
- data/lib/kangaroo/exception.rb +3 -0
- data/lib/kangaroo/hirb.rb +2 -1
- data/lib/kangaroo/model/associations.rb +33 -0
- data/lib/kangaroo/model/associations/many2one.rb +43 -0
- data/lib/kangaroo/model/associations/one2many.rb +41 -0
- data/lib/kangaroo/model/attributes.rb +88 -93
- data/lib/kangaroo/model/base.rb +44 -15
- data/lib/kangaroo/model/condition_normalizer.rb +7 -7
- data/lib/kangaroo/model/data_import.rb +28 -0
- data/lib/kangaroo/model/default_attributes.rb +20 -14
- data/lib/kangaroo/model/dynamic_finder.rb +42 -0
- data/lib/kangaroo/model/field.rb +52 -1
- data/lib/kangaroo/model/field/readonly.rb +39 -0
- data/lib/kangaroo/model/finder.rb +6 -2
- data/lib/kangaroo/model/inspector.rb +1 -4
- data/lib/kangaroo/model/mass_import.rb +42 -0
- data/lib/kangaroo/model/open_object_orm.rb +51 -5
- data/lib/kangaroo/model/persistence.rb +43 -19
- data/lib/kangaroo/model/readonly_attributes.rb +43 -0
- data/lib/kangaroo/model/relation.rb +40 -9
- data/lib/kangaroo/model/remote_execute.rb +1 -1
- data/lib/kangaroo/model/required_attributes.rb +26 -0
- data/lib/kangaroo/railtie.rb +13 -3
- data/lib/kangaroo/ruby_adapter/base.rb +2 -1
- data/lib/kangaroo/ruby_adapter/class_definition.rb +18 -3
- data/lib/kangaroo/ruby_adapter/fields.rb +27 -2
- data/lib/kangaroo/ruby_adapter/many2one.rb +38 -0
- data/lib/kangaroo/ruby_adapter/one2many.rb +31 -0
- data/lib/kangaroo/util/client.rb +29 -4
- data/lib/kangaroo/util/configuration.rb +15 -10
- data/lib/kangaroo/util/database.rb +8 -8
- data/lib/kangaroo/util/loader.rb +18 -22
- data/lib/kangaroo/util/loader/information_repository.rb +56 -0
- data/lib/kangaroo/util/loader/namespace.rb +1 -1
- data/lib/kangaroo/util/loader/reflection.rb +61 -0
- data/lib/kangaroo/util/loader/root_namespace.rb +12 -21
- data/lib/kangaroo/util/proxy.rb +9 -0
- data/lib/kangaroo/util/proxy/common.rb +28 -4
- data/lib/kangaroo/util/proxy/db.rb +14 -0
- data/lib/kangaroo/util/proxy/object.rb +40 -1
- data/lib/kangaroo/util/proxy/superadmin.rb +13 -0
- data/lib/kangaroo/version.rb +1 -1
- data/lib/kangaroo/viz.rb +1 -0
- data/lib/kangaroo/viz/base.rb +92 -0
- data/spec/commands/base_spec.rb +42 -0
- data/spec/functional/associations/many2one_spec.rb +72 -0
- data/spec/functional/associations/one2many_spec.rb +65 -0
- data/spec/functional/common_service_spec.rb +25 -0
- data/spec/functional/data_import_spec.rb +48 -0
- data/spec/functional/dynamic_finder_spec.rb +35 -0
- data/spec/functional/exception_handling_spec.rb +18 -0
- data/spec/functional/identity_spec.rb +48 -0
- data/spec/functional/import_export_spec.rb +39 -0
- data/spec/functional/lazy_loading_spec.rb +18 -11
- data/spec/functional/ordering_spec.rb +33 -0
- data/spec/functional/readonly_attributes_spec.rb +37 -0
- data/spec/functional/required_attributes_spec.rb +37 -0
- data/spec/functional/root_namespace_spec.rb +19 -0
- data/spec/functional/select_relation_spec.rb +26 -0
- data/spec/model/attributes_spec.rb +1 -0
- data/spec/model/base_spec.rb +1 -0
- data/spec/model/default_attributes_spec.rb +3 -1
- data/spec/model/finder_spec.rb +2 -1
- data/spec/model/inspector_spec.rb +1 -0
- data/spec/model/open_object_orm_spec.rb +5 -2
- data/spec/model/persistence_spec.rb +1 -0
- data/spec/model/relation_spec.rb +2 -2
- data/spec/ruby_adapter/class_definition_spec.rb +1 -0
- data/spec/server_helper.rb +0 -1
- data/spec/spec_helper.rb +4 -1
- data/spec/util/loader_spec.rb +6 -6
- metadata +152 -159
- data/Gemfile.lock +0 -69
- data/features/configuration.feature +0 -10
- data/features/env.rb +0 -8
- data/features/step_definitions/basic_steps.rb +0 -18
- data/features/step_definitions/configuration_steps.rb +0 -21
- data/features/support/test.yml +0 -11
- data/features/utility_services.feature +0 -33
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Kangaroo
|
4
|
+
describe 'Exception handling' do
|
5
|
+
before :all do
|
6
|
+
@config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
7
|
+
@config.login
|
8
|
+
|
9
|
+
Kangaroo::Util::Loader.new('res.partner', @config.database, 'ExceptionHandlingSpec').load!
|
10
|
+
end
|
11
|
+
|
12
|
+
it "catches missing methods" do
|
13
|
+
lambda {
|
14
|
+
@config.client.common.abcdef
|
15
|
+
}.should raise_error(NoMethodError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Kangaroo
|
4
|
+
describe 'Identity' do
|
5
|
+
before :all do
|
6
|
+
@config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
7
|
+
@config.login
|
8
|
+
|
9
|
+
Kangaroo::Util::Loader.new('res.partner', @config.database, 'IdentitySpec').load!
|
10
|
+
end
|
11
|
+
|
12
|
+
it ': Instances of same OpenERP object are considered equal' do
|
13
|
+
a = IdentitySpec::Res::Partner.first
|
14
|
+
b = IdentitySpec::Res::Partner.first
|
15
|
+
|
16
|
+
a.should == b
|
17
|
+
end
|
18
|
+
|
19
|
+
it ': Instances of different OpenERP objects are not equal' do
|
20
|
+
a, b = IdentitySpec::Res::Partner.all[0, 2]
|
21
|
+
|
22
|
+
a.should_not == b
|
23
|
+
end
|
24
|
+
|
25
|
+
it ': New records are not equal to anything' do
|
26
|
+
a = IdentitySpec::Res::Partner.first
|
27
|
+
b = IdentitySpec::Res::Partner.new
|
28
|
+
c = IdentitySpec::Res::Partner.new
|
29
|
+
|
30
|
+
a.should_not == b
|
31
|
+
b.should_not == c
|
32
|
+
end
|
33
|
+
|
34
|
+
it ': Instances of different models are always not equal' do
|
35
|
+
a = IdentitySpec::Res::Partner.find 1
|
36
|
+
b = IdentitySpec::Res::Country.find 1
|
37
|
+
|
38
|
+
a.should_not == b
|
39
|
+
end
|
40
|
+
|
41
|
+
it ': Arrays of same instances should be equal' do
|
42
|
+
a = IdentitySpec::Res::Partner.first
|
43
|
+
b = IdentitySpec::Res::Partner.first
|
44
|
+
|
45
|
+
[a].should == [b]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Kangaroo
|
4
|
+
describe 'Import / Export' do
|
5
|
+
before :all do
|
6
|
+
@config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
7
|
+
@config.login
|
8
|
+
|
9
|
+
Kangaroo::Util::Loader.new('res.partner', @config.database, 'ImportExportSpec').load!
|
10
|
+
end
|
11
|
+
|
12
|
+
after :each do
|
13
|
+
@cleanup && @cleanup.call
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'exports records' do
|
17
|
+
ids = ImportExportSpec::Res::Partner.select(:id).limit(3).all.map &:id
|
18
|
+
|
19
|
+
exported = ImportExportSpec::Res::Partner.export_data ids, [:name, :id]
|
20
|
+
|
21
|
+
exported.should be_a(Array)
|
22
|
+
exported.first.should be_a(Array)
|
23
|
+
exported.first.length.should == 2
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'imports records' do
|
27
|
+
name = ImportExportSpec::Res::Partner.find(1).name
|
28
|
+
|
29
|
+
@cleanup = lambda do
|
30
|
+
partner = ImportExportSpec::Res::Partner.find(1)
|
31
|
+
partner.name = name
|
32
|
+
partner.save!
|
33
|
+
end
|
34
|
+
|
35
|
+
ImportExportSpec::Res::Partner.import_data [".id", "name"], [[1, "XYZ"]]
|
36
|
+
ImportExportSpec::Res::Partner.find(1).name.should == "XYZ"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,41 +1,48 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
3
|
module Kangaroo
|
5
4
|
describe 'Lazy Loading' do
|
6
5
|
before :all do
|
7
6
|
config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
8
7
|
config.login
|
9
8
|
|
10
|
-
Kangaroo::Util::Loader.new('res.partner', config.database).load!
|
9
|
+
Kangaroo::Util::Loader.new('res.partner', config.database, 'LazyLoadSpec').load!
|
11
10
|
end
|
12
11
|
|
13
|
-
it '
|
12
|
+
it 'raises an error if trying to access constant without corresponding OpenERP Model' do
|
14
13
|
lambda {
|
15
|
-
|
14
|
+
LazyLoadSpec::Abcd
|
16
15
|
}.should raise_error
|
17
16
|
|
18
17
|
lambda {
|
19
|
-
|
18
|
+
LazyLoadSpec::Res::Bcde
|
20
19
|
}.should raise_error
|
21
20
|
end
|
22
21
|
|
23
|
-
it '
|
22
|
+
it 'lazy loads additional models in an OpenERP namespace' do
|
23
|
+
lambda {
|
24
|
+
LazyLoadSpec::Res::Country
|
25
|
+
}.should_not raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'creates namespace modules on demand' do
|
24
29
|
lambda {
|
25
|
-
|
30
|
+
LazyLoadSpec::Product
|
26
31
|
}.should_not raise_error
|
27
32
|
end
|
28
33
|
|
29
|
-
it '
|
34
|
+
it 'lazy loads missing models in other namespaces' do
|
30
35
|
lambda {
|
31
|
-
|
36
|
+
LazyLoadSpec::Product::Product
|
32
37
|
}.should_not raise_error
|
33
38
|
end
|
34
39
|
|
35
|
-
it '
|
40
|
+
it 'lazy loads nested models' do
|
36
41
|
lambda {
|
37
|
-
|
42
|
+
LazyLoadSpec::Sale::Order::Line
|
38
43
|
}.should_not raise_error
|
44
|
+
|
45
|
+
LazyLoadSpec::Sale::Order.should be_a(Class)
|
39
46
|
end
|
40
47
|
end
|
41
48
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Kangaroo
|
4
|
+
describe 'Ordering' do
|
5
|
+
before :all do
|
6
|
+
@config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
7
|
+
@config.login
|
8
|
+
|
9
|
+
Kangaroo::Util::Loader.new('res.partner', @config.database, 'OrderingSpec').load!
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'can order by id descending' do
|
13
|
+
partners = OrderingSpec::Res::Partner.order('id desc').select(:id).all
|
14
|
+
|
15
|
+
partners[1..-1].each_with_index do |p, i|
|
16
|
+
partners[i].id.should > p.id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can reverse queries with default ordering' do
|
21
|
+
partners = OrderingSpec::Res::Partner.select(:id).all
|
22
|
+
reversed_partners = OrderingSpec::Res::Partner.reverse.select(:id).all
|
23
|
+
|
24
|
+
partners.should == reversed_partners.reverse
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can return last element' do
|
28
|
+
last = OrderingSpec::Res::Partner.last
|
29
|
+
|
30
|
+
last.should == OrderingSpec::Res::Partner.all.last
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Kangaroo
|
4
|
+
module Model
|
5
|
+
describe ReadonlyAttributes do
|
6
|
+
before :all do
|
7
|
+
config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
8
|
+
config.login
|
9
|
+
|
10
|
+
Kangaroo::Util::Loader.new('res.partner', config.database, 'ReadonlyAttributesSpec').load!
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'raises error if trying to write readonly attributes' do
|
14
|
+
sale_order = ReadonlyAttributesSpec.by_xml_id :sale, :order
|
15
|
+
|
16
|
+
ReadonlyAttributesSpec::Sale::Order.fields_hash[:amount_untaxed].readonly?.should == true
|
17
|
+
|
18
|
+
lambda {
|
19
|
+
sale_order.amount_untaxed = 200
|
20
|
+
}.should raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'does not raise error if in state where writing is allowed' do
|
24
|
+
sale_order = ReadonlyAttributesSpec.by_xml_id :sale, :order
|
25
|
+
|
26
|
+
# Asserting the assumptions, in case OpenERPs demo data changes
|
27
|
+
ReadonlyAttributesSpec::Sale::Order.fields_hash[:name].readonly?.should == true
|
28
|
+
ReadonlyAttributesSpec::Sale::Order.fields_hash[:name].readonly_in?('draft').should == false
|
29
|
+
sale_order.state.should == 'draft'
|
30
|
+
|
31
|
+
lambda {
|
32
|
+
sale_order.name = "abcd"
|
33
|
+
}.should_not raise_error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Kangaroo
|
4
|
+
describe Model::RequiredAttributes do
|
5
|
+
before :all do
|
6
|
+
config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
7
|
+
config.login
|
8
|
+
|
9
|
+
Kangaroo::Util::Loader.new('res.country', config.database, 'RequiredAttributesSpec').load!
|
10
|
+
end
|
11
|
+
|
12
|
+
after :each do
|
13
|
+
@cleanup && @cleanup.call
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'validates required fields' do
|
17
|
+
c = RequiredAttributesSpec::Res::Country.new :name => 'ABCXYZ'
|
18
|
+
|
19
|
+
c.valid?.should_not == true
|
20
|
+
c.errors.keys.should include :code
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'refuses to save invalid records' do
|
24
|
+
a = RequiredAttributesSpec::Res::Country.where(:name => 'ABCXYZ').first
|
25
|
+
a && a.destroy
|
26
|
+
|
27
|
+
c = RequiredAttributesSpec::Res::Country.new :name => 'ABCXYZ'
|
28
|
+
|
29
|
+
c.save.should_not == true
|
30
|
+
c.errors.keys.should include :code
|
31
|
+
|
32
|
+
lambda {
|
33
|
+
c.save!
|
34
|
+
}.should raise_error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Kangaroo
|
4
|
+
describe 'Root namespace' do
|
5
|
+
before :all do
|
6
|
+
config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
7
|
+
config.login
|
8
|
+
|
9
|
+
Kangaroo::Util::Loader.new('res.partner', config.database, 'RootNamespaceSpec').load!
|
10
|
+
end
|
11
|
+
|
12
|
+
it "gets objects by xml id" do
|
13
|
+
country = RootNamespaceSpec.by_xml_id :base, :de
|
14
|
+
|
15
|
+
country.should be_a(RootNamespaceSpec::Res::Country)
|
16
|
+
country.code.should == 'DE'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Kangaroo
|
5
|
+
describe 'Select Relation' do
|
6
|
+
before :all do
|
7
|
+
config = Kangaroo::Util::Configuration.new 'spec/test_env/test.yml'
|
8
|
+
config.login
|
9
|
+
|
10
|
+
Kangaroo::Util::Loader.new('res.partner', config.database, 'SelectRelationSpec').load!
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'adjusts "attribute_names" when record is fetched with select clause' do
|
14
|
+
partner = SelectRelationSpec::Res::Partner.select(:lang, :email).first
|
15
|
+
|
16
|
+
partner.attribute_names.should =~ %w(lang email)
|
17
|
+
SelectRelationSpec::Res::Partner.attribute_names.count.should > 2
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns only selected attributes' do
|
21
|
+
partner = SelectRelationSpec::Res::Partner.select(:lang, :email).first
|
22
|
+
|
23
|
+
partner.attributes.keys.should =~ %w(lang email)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/model/base_spec.rb
CHANGED
@@ -4,8 +4,9 @@ require 'kangaroo/model/base'
|
|
4
4
|
module Kangaroo
|
5
5
|
module Model
|
6
6
|
describe DefaultAttributes do
|
7
|
-
before :
|
7
|
+
before :each do
|
8
8
|
@klass = Class.new(Kangaroo::Model::Base)
|
9
|
+
@klass.stub!(:fields_hash).and_return({})
|
9
10
|
@klass.define_multiple_accessors :a, :b
|
10
11
|
end
|
11
12
|
|
@@ -24,6 +25,7 @@ module Kangaroo
|
|
24
25
|
|
25
26
|
it 'fetches default values via default_get on the object service' do
|
26
27
|
@klass = Class.new(Kangaroo::Model::Base)
|
28
|
+
@klass.stub!(:fields_hash).and_return({})
|
27
29
|
@klass.define_multiple_accessors :a, :b
|
28
30
|
@klass.field_names = %w(a b)
|
29
31
|
@klass.stub!(:remote).and_return mock('object_service')
|
data/spec/model/finder_spec.rb
CHANGED
@@ -8,6 +8,7 @@ module Kangaroo
|
|
8
8
|
|
9
9
|
before :each do
|
10
10
|
@klass = Class.new(Kangaroo::Model::Base)
|
11
|
+
@klass.stub!(:fields_hash).and_return({})
|
11
12
|
@klass.define_multiple_accessors :a, :b
|
12
13
|
@klass.stub!(:default_attributes).and_return({})
|
13
14
|
@remote_stub = mock 'remote'
|
@@ -91,7 +92,7 @@ module Kangaroo
|
|
91
92
|
@klass.first
|
92
93
|
end
|
93
94
|
end
|
94
|
-
|
95
|
+
|
95
96
|
describe '#count' do
|
96
97
|
it 'only counts how many records are present' do
|
97
98
|
@remote_stub.should_receive(:search).with([], 0, anything, anything, anything, true).
|
@@ -9,6 +9,7 @@ module Kangaroo
|
|
9
9
|
|
10
10
|
before :each do
|
11
11
|
@klass = Class.new(Kangaroo::Model::Base)
|
12
|
+
@klass.stub!(:fields_hash).and_return({})
|
12
13
|
@klass.define_multiple_accessors :a, :b
|
13
14
|
@klass.stub!(:default_attributes).and_return({})
|
14
15
|
@klass.stub!(:remote).and_return proxy('object', 'some_class')
|
@@ -17,7 +18,7 @@ module Kangaroo
|
|
17
18
|
describe '#read' do
|
18
19
|
it 'reads and instantiates records' do
|
19
20
|
object_service.stub!(:xmlrpc_call).
|
20
|
-
with('execute', 'some_class', 'read', [1], ['a', 'b']).
|
21
|
+
with('execute', 'some_class', 'read', [1], ['a', 'b'], false).
|
21
22
|
and_return([{:a => 'one', :id => 1}])
|
22
23
|
@klass.read([1], :fields => ['a', 'b']).first.a.should == 'one'
|
23
24
|
end
|
@@ -29,7 +30,9 @@ module Kangaroo
|
|
29
30
|
end
|
30
31
|
|
31
32
|
it 'uses attribute_names as default value for field list' do
|
32
|
-
object_service.
|
33
|
+
object_service.
|
34
|
+
should_receive(:xmlrpc_call).
|
35
|
+
with('execute', 'some_class', 'read', [1], ['a', 'b'], false).
|
33
36
|
and_return([{:a => 'one', :id => 1}])
|
34
37
|
@klass.read([1])
|
35
38
|
end
|
data/spec/model/relation_spec.rb
CHANGED
@@ -72,8 +72,8 @@ module Kangaroo
|
|
72
72
|
end
|
73
73
|
|
74
74
|
describe '#reverse' do
|
75
|
-
it '
|
76
|
-
@relation.reverse.
|
75
|
+
it 'sets the reverse flag if no order was specified' do
|
76
|
+
@relation.reverse.reverse_flag.should == true
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'reverses previously specified orders' do
|