ditto 0.5.0 → 0.6.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.
- data/bin/ditto +1 -1
- data/features/create_entities.feature +1 -0
- data/features/load_entity.feature +1 -0
- data/features/store_entity.feature +5 -4
- data/lib/ditto.rb +1 -0
- data/lib/ditto/dsl.rb +14 -9
- data/lib/ditto/entity.rb +118 -106
- data/lib/ditto/error.rb +19 -0
- data/lib/ditto/options.rb +45 -13
- data/lib/ditto/runner.rb +37 -56
- data/lib/ditto/version.rb +1 -1
- data/spec/entity_spec.rb +83 -59
- data/spec/fixtures/badmap.ditto +18 -0
- data/spec/fixtures/badver.ditto +17 -0
- data/spec/fixtures/bigcircle.ditto +17 -0
- data/spec/fixtures/circle.ditto +16 -0
- data/spec/fixtures/continent.ditto +16 -0
- data/spec/fixtures/country.ditto +16 -0
- data/spec/fixtures/currency.ditto +30 -0
- data/spec/fixtures/currency_group.ditto +17 -0
- data/spec/fixtures/dot.ditto +17 -0
- data/spec/fixtures/dupversion.ditto +32 -0
- data/spec/fixtures/good.ditto +17 -0
- data/spec/fixtures/multiversion.ditto +32 -0
- data/spec/fixtures/nocomma.ditto +16 -0
- data/spec/fixtures/nomethod.ditto +18 -0
- data/spec/fixtures/random.ditto +17 -0
- data/spec/fixtures/syntax.ditto +19 -0
- data/spec/options_spec.rb +43 -25
- data/test/data/simple_object.xml +23 -0
- data/test/data/simple_object.yaml +39 -0
- data/test/ditto/currency.ditto +30 -0
- data/test/ditto/currency_group.ditto +17 -0
- data/test/dm/currency-1.0.0.dm +13 -0
- data/test/dm/currency_group-1.0.0.dm +10 -0
- data/test/dm/datamart-1.0 +7 -0
- data/test/dm/nested +2 -0
- data/test/dmtest.rb +41 -0
- data/test/sample.test +2 -0
- metadata +59 -42
- data/lib/ditto/map.rb +0 -39
@@ -0,0 +1,17 @@
|
|
1
|
+
# Ditto entity definitions and mappings for dot
|
2
|
+
# A circular dependency with bigcircle
|
3
|
+
#
|
4
|
+
|
5
|
+
entity :dot, '1.0.0', {
|
6
|
+
code: [ :mandatory, :unique ],
|
7
|
+
description: nil,
|
8
|
+
bigcircle: :related
|
9
|
+
},
|
10
|
+
add(Dot: '~>1.0') { |ditto|
|
11
|
+
Dot.create(
|
12
|
+
:code => ditto.code,
|
13
|
+
:description => ditto.description,
|
14
|
+
:bigcircle => ditto.bigcircle
|
15
|
+
)
|
16
|
+
}
|
17
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Duplicate version entity definition file
|
2
|
+
#
|
3
|
+
|
4
|
+
entity :currency_group, '1.0.0', {
|
5
|
+
:code => [ :mandatory, :unique ],
|
6
|
+
:description => nil,
|
7
|
+
:is_commodity => nil
|
8
|
+
},
|
9
|
+
add(CurrencyGroup: '=1.0.0') { |ditto|
|
10
|
+
CurrencyGroup.create(
|
11
|
+
:code => ditto.code,
|
12
|
+
:description => ditto.description,
|
13
|
+
:is_commodity => ditto.is_commodity
|
14
|
+
)
|
15
|
+
}
|
16
|
+
|
17
|
+
entity :currency_group, '1.0.0', {
|
18
|
+
:code => [ :mandatory, :unique ],
|
19
|
+
:description => nil,
|
20
|
+
:continent => nil,
|
21
|
+
:is_commodity => nil
|
22
|
+
},
|
23
|
+
add(CurrencyGroup: '=2.0.0') { |ditto|
|
24
|
+
CurrencyGroup.create(
|
25
|
+
:code => ditto.code,
|
26
|
+
:description => ditto.description,
|
27
|
+
:continent => ditto.continent,
|
28
|
+
:is_commodity => ditto.is_commodity
|
29
|
+
)
|
30
|
+
}
|
31
|
+
|
32
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Correct simple ditto entity definition file
|
2
|
+
#
|
3
|
+
|
4
|
+
entity :currency_group, '1.0.0', {
|
5
|
+
:code => [ :mandatory, :unique ],
|
6
|
+
:description => nil,
|
7
|
+
:is_commodity => nil
|
8
|
+
},
|
9
|
+
add(CurrencyGroup: '=1.0.0') { |ditto|
|
10
|
+
CurrencyGroup.create(
|
11
|
+
:code => ditto.code,
|
12
|
+
:description => ditto.description,
|
13
|
+
:is_commodity => ditto.is_commodity
|
14
|
+
)
|
15
|
+
}
|
16
|
+
|
17
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Correct multiple version entity definition
|
2
|
+
#
|
3
|
+
|
4
|
+
entity :currency_group, '1.0.0', {
|
5
|
+
:code => [ :mandatory, :unique ],
|
6
|
+
:description => nil,
|
7
|
+
:is_commodity => nil
|
8
|
+
},
|
9
|
+
add(CurrencyGroup: '=1.0.0') { |ditto|
|
10
|
+
CurrencyGroup.create(
|
11
|
+
:code => ditto.code,
|
12
|
+
:description => ditto.description,
|
13
|
+
:is_commodity => ditto.is_commodity
|
14
|
+
)
|
15
|
+
}
|
16
|
+
|
17
|
+
entity :currency_group, '2.0.0', {
|
18
|
+
:code => [ :mandatory, :unique ],
|
19
|
+
:description => nil,
|
20
|
+
:continent => nil,
|
21
|
+
:is_commodity => nil
|
22
|
+
},
|
23
|
+
add(CurrencyGroup: '=2.0.0') { |ditto|
|
24
|
+
CurrencyGroup.create(
|
25
|
+
:code => ditto.code,
|
26
|
+
:description => ditto.description,
|
27
|
+
:continent => ditto.continent,
|
28
|
+
:is_commodity => ditto.is_commodity
|
29
|
+
)
|
30
|
+
}
|
31
|
+
|
32
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Missing add method (due to lack of comma)
|
2
|
+
#
|
3
|
+
entity :currency_group, '1.a.0', {
|
4
|
+
:code => [ :mandatory, :unique ],
|
5
|
+
:description => nil,
|
6
|
+
:is_commodity => nil
|
7
|
+
}
|
8
|
+
add(CurrencyGroup: '=1.0.0') { |ditto|
|
9
|
+
CurrencyGroup.create(
|
10
|
+
:code => ditto.code,
|
11
|
+
:description => ditto.description,
|
12
|
+
:is_commodity => ditto.is_commodity
|
13
|
+
)
|
14
|
+
}
|
15
|
+
|
16
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Missing method error in a ditto file
|
2
|
+
#
|
3
|
+
zarg
|
4
|
+
|
5
|
+
entity :currency_group, '1.0.0', {
|
6
|
+
:code => [ :mandatory, :unique ],
|
7
|
+
:description => nil,
|
8
|
+
:is_commodity => nil
|
9
|
+
},
|
10
|
+
add(CurrencyGroup: '=1.0.0') { |ditto|
|
11
|
+
CurrencyGroup.create(
|
12
|
+
:code => ditto.code,
|
13
|
+
:description => ditto.description,
|
14
|
+
:is_commodity => ditto.is_commodity
|
15
|
+
)
|
16
|
+
}
|
17
|
+
|
18
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Ditto entity definitions and mappings for random
|
2
|
+
# contains a missing relation
|
3
|
+
#
|
4
|
+
|
5
|
+
entity :random, '1.0.0', {
|
6
|
+
code: [ :mandatory, :unique ],
|
7
|
+
description: nil,
|
8
|
+
stealth: :related
|
9
|
+
},
|
10
|
+
add(Random: '~>1.0') { |ditto|
|
11
|
+
Random.create(
|
12
|
+
:code => ditto.code,
|
13
|
+
:description => ditto.description,
|
14
|
+
:stealth => ditto.stealth
|
15
|
+
)
|
16
|
+
}
|
17
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Syntax error in a ditto file
|
2
|
+
#
|
3
|
+
|
4
|
+
---+++
|
5
|
+
|
6
|
+
entity :currency_group, '1.0.0', {
|
7
|
+
:code => [ :mandatory, :unique ],
|
8
|
+
:description => nil,
|
9
|
+
:is_commodity => nil
|
10
|
+
},
|
11
|
+
add(CurrencyGroup: '=1.0.0') { |ditto|
|
12
|
+
CurrencyGroup.create(
|
13
|
+
:code => ditto.code,
|
14
|
+
:description => ditto.description,
|
15
|
+
:is_commodity => ditto.is_commodity
|
16
|
+
)
|
17
|
+
}
|
18
|
+
|
19
|
+
# vim: set ft=ruby:
|
data/spec/options_spec.rb
CHANGED
@@ -1,75 +1,93 @@
|
|
1
1
|
require_relative '../lib/ditto/options'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tmpdir'
|
2
4
|
|
3
5
|
module Ditto
|
4
6
|
describe Options do
|
7
|
+
before(:all) do
|
8
|
+
@tempdir = Dir.tmpdir
|
9
|
+
@file1 = "#{@tempdir}/file1"
|
10
|
+
@file2 = "#{@tempdir}/file2"
|
11
|
+
FileUtils.touch [@file1, @file2]
|
12
|
+
# ENV.delete 'DITTO_MART'
|
13
|
+
end
|
14
|
+
after(:all) do
|
15
|
+
FileUtils.rm_f [@file1, @file2]
|
16
|
+
end
|
5
17
|
context "specifying no options" do
|
6
18
|
it "should return defaults" do
|
7
|
-
opts = Ditto::Options.
|
8
|
-
opts.parse([])
|
19
|
+
opts = Ditto::Options.new([])
|
9
20
|
opts.connstring.should == Ditto::Options::DEFAULTS[:connstring]
|
10
|
-
opts.
|
21
|
+
opts.dittomart.should == Ditto::Options::DEFAULTS[:dittomart]
|
22
|
+
opts.entitydir.should == Ditto::Options::DEFAULTS[:entitydir]
|
11
23
|
opts.verbose.should == 0
|
12
24
|
opts.debug.should be_false
|
13
25
|
opts.droptables.should be_false
|
14
|
-
opts.
|
26
|
+
opts.loadfiles.size.should == 0
|
15
27
|
end
|
16
28
|
it "should return single path" do
|
17
|
-
opts = Ditto::Options.
|
29
|
+
opts = Ditto::Options.new([@file1])
|
18
30
|
opts.connstring.should == Ditto::Options::DEFAULTS[:connstring]
|
19
|
-
opts.
|
31
|
+
opts.dittomart.should == Ditto::Options::DEFAULTS[:dittomart]
|
20
32
|
opts.verbose.should == 0
|
21
33
|
opts.debug.should be_false
|
22
34
|
opts.droptables.should be_false
|
23
|
-
opts.
|
35
|
+
opts.loadfiles.should == [@file1]
|
24
36
|
end
|
25
37
|
end
|
26
|
-
context "specifying a
|
38
|
+
context "specifying a dittomart" do
|
27
39
|
it "should return it" do
|
28
|
-
|
29
|
-
opts
|
30
|
-
opts.modelpath.should == mpath
|
40
|
+
opts = Ditto::Options.new(["-m", @file1])
|
41
|
+
opts.dittomart.should == @file1
|
31
42
|
end
|
32
43
|
end
|
33
|
-
context "specifying a
|
44
|
+
context "specifying a dittomart that doesn't exist" do
|
34
45
|
it "should fail" do
|
35
|
-
mpath = "zz/zz/zz/zz"
|
36
46
|
expect {
|
37
|
-
opts = Ditto::Options.
|
38
|
-
}.to raise_error(
|
47
|
+
opts = Ditto::Options.new(["-m", "zz/zz/zz"])
|
48
|
+
}.to raise_error(Errno::ENOENT)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
context "not specifying a dittomart" do
|
52
|
+
it "should default to the environment" do
|
53
|
+
pending "Can't work out how to set ENV within an rspec test"
|
54
|
+
ENV['DITTO_MART'] = @file1
|
55
|
+
opts = Ditto::Options.new([@file2])
|
56
|
+
opts.dittomart.should == @file1
|
39
57
|
end
|
40
58
|
end
|
41
59
|
context "specifying a connection string" do
|
42
60
|
it "should return it" do
|
43
61
|
mydb = "username/password@//myserver:1521/my.service.com"
|
44
|
-
opts = Ditto::Options.
|
62
|
+
opts = Ditto::Options.new(["-c", "#{mydb}"])
|
45
63
|
opts.connstring.should == mydb
|
46
64
|
end
|
47
65
|
end
|
48
|
-
context "specifying
|
49
|
-
it "should return the
|
50
|
-
opts = Ditto::Options.
|
51
|
-
opts.
|
66
|
+
context "specifying files and no connection string" do
|
67
|
+
it "should return the files" do
|
68
|
+
opts = Ditto::Options.new([@file1, @file2])
|
69
|
+
opts.loadfiles.should == [@file1, @file2]
|
52
70
|
end
|
53
71
|
end
|
54
72
|
context "specifying files and a connection string" do
|
55
73
|
it "should return the files" do
|
56
|
-
opts = Ditto::Options.
|
57
|
-
opts.
|
74
|
+
opts = Ditto::Options.new(["-c", "u/p@//serv:1521/mydb", @file1, @file2])
|
75
|
+
opts.loadfiles.should == [@file1, @file2]
|
58
76
|
end
|
59
77
|
end
|
60
78
|
context "specifying droptables" do
|
61
79
|
it "should set the options" do
|
62
|
-
opts = Ditto::Options.
|
80
|
+
opts = Ditto::Options.new(["--droptables"])
|
63
81
|
opts.droptables.should be_true
|
64
82
|
end
|
65
83
|
end
|
66
84
|
context "specifying verbose" do
|
67
85
|
it "should set verbose flag" do
|
68
|
-
opts = Ditto::Options.
|
86
|
+
opts = Ditto::Options.new(["-v"])
|
69
87
|
opts.verbose.should == 1
|
70
88
|
end
|
71
89
|
it "should set verbose flag twice" do
|
72
|
-
opts = Ditto::Options.
|
90
|
+
opts = Ditto::Options.new(["-vv"])
|
73
91
|
opts.verbose.should == 2
|
74
92
|
end
|
75
93
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---------------------------------------- DEFINITIONS ----------------------------------------
|
2
|
+
<object_classes>
|
3
|
+
<object name='currency'>
|
4
|
+
<property name='code' mandatory='Y' is_key='Y' />
|
5
|
+
<property name='description'/>
|
6
|
+
<property name='exchange_rate' mandatory='Y' />
|
7
|
+
<property name='is_designated'/>
|
8
|
+
<relation name='currency_group' relation_object='currency_group' relation_type='unique'/>
|
9
|
+
</object>
|
10
|
+
<object name='currency_group'>
|
11
|
+
<property name='code' mandatory='Y' is_key='Y'/>
|
12
|
+
<property name='description'/>
|
13
|
+
<property name='is_commodity'/>
|
14
|
+
</object>
|
15
|
+
</object_classes>
|
16
|
+
|
17
|
+
---------------------------------------- DATA ----------------------------------------
|
18
|
+
<object_instances>
|
19
|
+
<currency code ='GBP' description='Great Britain Pound' exchange_rate='1.5' is_designated='false'>
|
20
|
+
<currency_group code='Europe' />
|
21
|
+
</currency>
|
22
|
+
<currency_group code='Europe' description='European countries' is_commodity='false'/>
|
23
|
+
</object_instances>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This format has multiple YAML documents:
|
2
|
+
# The first contains version info, date and author etc.
|
3
|
+
# The subsequent are hashes, each being an entity with key the entity name
|
4
|
+
# Note that strings are used as keys and not symbols for user clarity
|
5
|
+
#
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2012-10-13
|
8
|
+
author: Nick Townsend
|
9
|
+
---
|
10
|
+
currency_group:
|
11
|
+
code: Americas
|
12
|
+
description: The Americas
|
13
|
+
is_commodity: true
|
14
|
+
---
|
15
|
+
currency:
|
16
|
+
code: USD
|
17
|
+
description: United States Dollar
|
18
|
+
exchange_rate: 1.0
|
19
|
+
is_designated: false
|
20
|
+
currency_group: Americas
|
21
|
+
---
|
22
|
+
currency_group:
|
23
|
+
code: Europe
|
24
|
+
description: European Countries
|
25
|
+
is_commodity: false
|
26
|
+
---
|
27
|
+
currency:
|
28
|
+
code: GBP
|
29
|
+
description: Pounds Sterling
|
30
|
+
exchange_rate: 1.5
|
31
|
+
is_designated: false
|
32
|
+
currency_group: Europe
|
33
|
+
---
|
34
|
+
currency:
|
35
|
+
code: EUR
|
36
|
+
description: Euro
|
37
|
+
exchange_rate: 1.2
|
38
|
+
is_designated: false
|
39
|
+
currency_group: Europe
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Ditto entity definitions and mappings for currency
|
2
|
+
#
|
3
|
+
|
4
|
+
entity :currency, '1.0.0', {
|
5
|
+
code: [ :mandatory, :unique ],
|
6
|
+
description: nil,
|
7
|
+
exchange_rate: :mandatory,
|
8
|
+
is_designated: nil,
|
9
|
+
currency_group: :related
|
10
|
+
},
|
11
|
+
add(Currency: '~>1.0', CurrencyGroup: '~>1.0') { |ditto|
|
12
|
+
cg = CurrencyGroup.get(ditto.currency_group)
|
13
|
+
cg.currencies.create(
|
14
|
+
:code => ditto.code,
|
15
|
+
:description => ditto.description,
|
16
|
+
:exchange_rate => ditto.exchange_rate,
|
17
|
+
:is_designated => ditto.is_designated
|
18
|
+
)
|
19
|
+
}
|
20
|
+
add(Currency: '~>2.0', CurrencyGroup: '~>2.0') { |ditto|
|
21
|
+
cg = CurrencyGroup.get(ditto.currency_group)
|
22
|
+
cg.currencies.create(
|
23
|
+
:code => ditto.code,
|
24
|
+
:description => ditto.description,
|
25
|
+
:index => 'ghost',
|
26
|
+
:exchange_rate => ditto.exchange_rate,
|
27
|
+
:is_designated => ditto.is_designated
|
28
|
+
)
|
29
|
+
}
|
30
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Ditto entity definitions and mappings for currency_group
|
2
|
+
#
|
3
|
+
|
4
|
+
entity :currency_group, '1.0.0', {
|
5
|
+
:code => [ :mandatory, :unique ],
|
6
|
+
:description => nil,
|
7
|
+
:is_commodity => nil
|
8
|
+
},
|
9
|
+
add(CurrencyGroup: '=1.0.0') { |ditto|
|
10
|
+
CurrencyGroup.create(
|
11
|
+
:code => ditto.code,
|
12
|
+
:description => ditto.description,
|
13
|
+
:is_commodity => ditto.is_commodity
|
14
|
+
)
|
15
|
+
}
|
16
|
+
|
17
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This class encapsulates the existing Currency database
|
2
|
+
#
|
3
|
+
class Currency
|
4
|
+
VERSION = '1.0.0'
|
5
|
+
include DataMapper::Resource
|
6
|
+
|
7
|
+
property :code, String, :key => true
|
8
|
+
property :description, Text, :required => true, :lazy => false
|
9
|
+
property :exchange_rate, Float, :default => 0.0
|
10
|
+
property :is_designated, Boolean, :default => false
|
11
|
+
|
12
|
+
belongs_to :currency_group
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# This class encapsulates the existing Currency Group database
|
2
|
+
#
|
3
|
+
class CurrencyGroup
|
4
|
+
VERSION = '1.0.0'
|
5
|
+
include DataMapper::Resource
|
6
|
+
property :code, String, :key => true
|
7
|
+
property :description, Text, :required => true, :lazy => false
|
8
|
+
property :is_commodity,Boolean, :default => false
|
9
|
+
has n, :currencies
|
10
|
+
end
|