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.
Files changed (41) hide show
  1. data/bin/ditto +1 -1
  2. data/features/create_entities.feature +1 -0
  3. data/features/load_entity.feature +1 -0
  4. data/features/store_entity.feature +5 -4
  5. data/lib/ditto.rb +1 -0
  6. data/lib/ditto/dsl.rb +14 -9
  7. data/lib/ditto/entity.rb +118 -106
  8. data/lib/ditto/error.rb +19 -0
  9. data/lib/ditto/options.rb +45 -13
  10. data/lib/ditto/runner.rb +37 -56
  11. data/lib/ditto/version.rb +1 -1
  12. data/spec/entity_spec.rb +83 -59
  13. data/spec/fixtures/badmap.ditto +18 -0
  14. data/spec/fixtures/badver.ditto +17 -0
  15. data/spec/fixtures/bigcircle.ditto +17 -0
  16. data/spec/fixtures/circle.ditto +16 -0
  17. data/spec/fixtures/continent.ditto +16 -0
  18. data/spec/fixtures/country.ditto +16 -0
  19. data/spec/fixtures/currency.ditto +30 -0
  20. data/spec/fixtures/currency_group.ditto +17 -0
  21. data/spec/fixtures/dot.ditto +17 -0
  22. data/spec/fixtures/dupversion.ditto +32 -0
  23. data/spec/fixtures/good.ditto +17 -0
  24. data/spec/fixtures/multiversion.ditto +32 -0
  25. data/spec/fixtures/nocomma.ditto +16 -0
  26. data/spec/fixtures/nomethod.ditto +18 -0
  27. data/spec/fixtures/random.ditto +17 -0
  28. data/spec/fixtures/syntax.ditto +19 -0
  29. data/spec/options_spec.rb +43 -25
  30. data/test/data/simple_object.xml +23 -0
  31. data/test/data/simple_object.yaml +39 -0
  32. data/test/ditto/currency.ditto +30 -0
  33. data/test/ditto/currency_group.ditto +17 -0
  34. data/test/dm/currency-1.0.0.dm +13 -0
  35. data/test/dm/currency_group-1.0.0.dm +10 -0
  36. data/test/dm/datamart-1.0 +7 -0
  37. data/test/dm/nested +2 -0
  38. data/test/dmtest.rb +41 -0
  39. data/test/sample.test +2 -0
  40. metadata +59 -42
  41. 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:
@@ -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.instance
8
- opts.parse([])
19
+ opts = Ditto::Options.new([])
9
20
  opts.connstring.should == Ditto::Options::DEFAULTS[:connstring]
10
- opts.modelpath.should == Ditto::Options::DEFAULTS[:modelpath]
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.loadpaths.size.should == 0
26
+ opts.loadfiles.size.should == 0
15
27
  end
16
28
  it "should return single path" do
17
- opts = Ditto::Options.instance.parse(["testfile"])
29
+ opts = Ditto::Options.new([@file1])
18
30
  opts.connstring.should == Ditto::Options::DEFAULTS[:connstring]
19
- opts.modelpath.should == Ditto::Options::DEFAULTS[:modelpath]
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.loadpaths.should == ["testfile"]
35
+ opts.loadfiles.should == [@file1]
24
36
  end
25
37
  end
26
- context "specifying a model path" do
38
+ context "specifying a dittomart" do
27
39
  it "should return it" do
28
- mpath = "spec"
29
- opts = Ditto::Options.instance.parse(["-m", "#{mpath}", "afile"])
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 model path that doesn't exist" do
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.instance.parse(["-m", "#{mpath}", "afile"])
38
- }.to raise_error(RuntimeError, "Modelpath #{mpath} does not exist!")
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.instance.parse(["-c", "#{mydb}", "afile"])
62
+ opts = Ditto::Options.new(["-c", "#{mydb}"])
45
63
  opts.connstring.should == mydb
46
64
  end
47
65
  end
48
- context "specifying paths and no connection string" do
49
- it "should return the paths" do
50
- opts = Ditto::Options.instance.parse(["file1", "path1"])
51
- opts.loadpaths.should == ["file1", "path1"]
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.instance.parse(["-c", "u/p@//serv:1521/mydb", "file1", "path1"])
57
- opts.loadpaths.should == ["file1", "path1"]
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.instance.parse(["--droptables", "file1", "path1"])
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.instance.parse(["-v", "file1"])
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.instance.parse(["-vv", "file1"])
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
@@ -0,0 +1,7 @@
1
+ # This is a test file
2
+
3
+ currency-1.0.0.dm
4
+
5
+ @nested
6
+
7
+ currency_group-1.0.0.dm