deploy_couch 0.0.1

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 (37) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +14 -0
  4. data/README +0 -0
  5. data/Rakefile +1 -0
  6. data/bin/deploy_couch +16 -0
  7. data/deploy_couch.gemspec +20 -0
  8. data/deploy_couch.rake +0 -0
  9. data/lib/deploy_couch/config.rb +44 -0
  10. data/lib/deploy_couch/couch_db_schema.rb +58 -0
  11. data/lib/deploy_couch/delta.rb +36 -0
  12. data/lib/deploy_couch/delta_loader.rb +37 -0
  13. data/lib/deploy_couch/delta_processor.rb +60 -0
  14. data/lib/deploy_couch/deploy.rb +70 -0
  15. data/lib/deploy_couch/http_client.rb +48 -0
  16. data/lib/deploy_couch/repository.rb +71 -0
  17. data/lib/deploy_couch/version.rb +3 -0
  18. data/lib/deploy_couch.rb +13 -0
  19. data/spec/couchdb.yml +6 -0
  20. data/spec/integration/config_spec.rb +41 -0
  21. data/spec/integration/database_populator.rb +37 -0
  22. data/spec/integration/delta_loader_spec.rb +54 -0
  23. data/spec/integration/delta_processor_spec.rb +52 -0
  24. data/spec/integration/deltas/11_update_phone_with_std_codes.yml +13 -0
  25. data/spec/integration/deltas/12_delete_customer_name_1.yml +19 -0
  26. data/spec/integration/deltas/13_copy_and_create_new_customer.yml +20 -0
  27. data/spec/integration/deltas/1_add_address_to_customer.yml +14 -0
  28. data/spec/integration/deltas/2_add_phone_to_customer.yml +13 -0
  29. data/spec/integration/deltas/5_not_a_yaml_file.rb +0 -0
  30. data/spec/integration/deploy_spec.rb +56 -0
  31. data/spec/integration/repository_spec.rb +40 -0
  32. data/spec/spec_helper.rb +17 -0
  33. data/spec/unit/db_schema_spec.rb +66 -0
  34. data/spec/unit/delta_processor_spec.rb +61 -0
  35. data/spec/unit/deploy_spec.rb +94 -0
  36. data/spec/unit/repository_spec.rb +128 -0
  37. metadata +102 -0
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in deploy_couch.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,14 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ deploy_couch (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+
10
+ PLATFORMS
11
+ ruby
12
+
13
+ DEPENDENCIES
14
+ deploy_couch!
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/deploy_couch ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if (ARGV.length != 1)
4
+ puts "usage: deploy_couch 'path/to/couchdb.yml' "
5
+ exit(-1)
6
+ end
7
+ if (!File.exists?(ARGV[0]))
8
+ puts "file '#{ARGV[0]}' does not exist "
9
+ exit(-1)
10
+ end
11
+
12
+ require 'deploy_couch'
13
+
14
+ config = DeployCouch::Config.create_from_file(ARGV[0])
15
+ deploy = DeployCouch::Deploy.new(config)
16
+ deploy.run
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "deploy_couch/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "deploy_couch"
7
+ s.version = DeployCouch::VERSION
8
+ s.authors = ["venky/mln"]
9
+ s.email = ["venkatesh.swdev@gmail.com"]
10
+ s.homepage = "https://github.com/venkateshcm/deploy_couch"
11
+ s.summary = "dbDeploy for couchdb"
12
+ s.description = "dbDeploy for couchdb"
13
+
14
+ s.rubyforge_project = "deploy_couch"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
data/deploy_couch.rake ADDED
File without changes
@@ -0,0 +1,44 @@
1
+ module DeployCouch
2
+
3
+ class Config
4
+
5
+ def initialize(config)
6
+ @config = config
7
+ end
8
+
9
+ def self.create_from_file(config_file)
10
+ config = YAML.load_file(config_file)
11
+ config = config.merge("config_folder_path" => File.dirname(config_file))
12
+ Config.new(config)
13
+ end
14
+
15
+ def hostname
16
+ @config["hostname"]
17
+ end
18
+
19
+ def port
20
+ @config["port"]
21
+ end
22
+
23
+ def delta_path
24
+ @config["config_folder_path"] + "/" + @config["delta_path"]
25
+ end
26
+
27
+ def database
28
+ @config["database"]
29
+ end
30
+
31
+ def doc_type_field
32
+ @config["doc_type_field"]
33
+ end
34
+
35
+ def type_version_field
36
+ @config["type_version_field"]
37
+ end
38
+
39
+ def merge_config(config)
40
+ @config = @config.merge(config)
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,58 @@
1
+ module DeployCouch
2
+
3
+ class DbSchema
4
+
5
+ def initialize(schema,repository)
6
+ @schema = schema
7
+ @repository = repository
8
+ end
9
+
10
+ def self.load_or_create(config,repository)
11
+ default_schema = {"_id"=>"schema__schema_document_key__",config.doc_type_field=>"__schema__", 'applied_deltas'=>[], "type_versions"=>{}}
12
+ schema = repository.get_schema
13
+ if (schema.nil?)
14
+ repository.create_schema(default_schema)
15
+ schema = repository.get_schema
16
+ end
17
+ DbSchema.new(schema,repository)
18
+ end
19
+
20
+ def applied_deltas
21
+ @schema["applied_deltas"]
22
+ end
23
+
24
+ def type_versions
25
+ @schema["type_versions"]
26
+ end
27
+
28
+ def get_next_type_version_for(type)
29
+ current_version = type_versions[type]
30
+ current_version = 0 if current_version.nil?
31
+ current_version += 1
32
+ end
33
+
34
+ def type_version_field
35
+ @schema["type_version_field"]
36
+ end
37
+
38
+ def completed(delta)
39
+ @schema['applied_deltas'].push(delta.id)
40
+ current_type_version = @schema['type_versions'].has_key?(delta.type) ? @schema['type_versions'][delta.type] : 0
41
+ @schema['type_versions'][delta.type] = current_type_version + 1
42
+
43
+ @repository.put_document(@schema)
44
+ @schema = @repository.get_schema
45
+ end
46
+
47
+ def rollback(delta)
48
+ @schema['applied_deltas'].delete(delta.id)
49
+ current_type_version = @schema['type_versions'].has_key?(delta.type) ? @schema['type_versions'][delta.type] : 0
50
+ @schema['type_versions'][delta.type] = current_type_version - 1
51
+
52
+ @repository.put_document(@schema)
53
+ @schema = @repository.get_schema
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,36 @@
1
+ module DeployCouch
2
+
3
+ class Delta
4
+ def initialize(id,file_name,type,map_function,rollback_function)
5
+ @id=id
6
+ @file_name = file_name
7
+ @type = type
8
+ @map_function = map_function
9
+ @rollback_function = rollback_function
10
+ end
11
+
12
+ def id
13
+ @id
14
+ end
15
+
16
+
17
+ def file_name
18
+ @file_name
19
+ end
20
+
21
+ def type
22
+ @type
23
+ end
24
+
25
+ def map_function
26
+ @map_function
27
+ end
28
+
29
+ def rollback_function
30
+ @rollback_function
31
+ end
32
+
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,37 @@
1
+ module DeployCouch
2
+
3
+ class DeltaLoader
4
+ def initialize(deltas_folder)
5
+ @deltas_folder = deltas_folder
6
+ end
7
+
8
+ def get_deltas
9
+ hash = {}
10
+ files = Dir["#{@deltas_folder}/*.yml"].select {|f| File.file?(f)}
11
+ files.each do |file|
12
+ file_name = File.basename(file)
13
+ key = file_name.split('_')[0].to_i
14
+ if (key == 0)
15
+ e = RuntimeError.new("invalid file name #{file_name}")
16
+ raise e
17
+ end
18
+ if (hash.has_key?(key))
19
+ e = RuntimeError.new("duplicate key found in file #{file_name}")
20
+ raise e
21
+ end
22
+
23
+ hash[key] = convert_to_delta(key,file)
24
+ end
25
+ hash
26
+ end
27
+
28
+ def convert_to_delta(id, file)
29
+ delta_config = YAML.load_file(file)
30
+ file_name = File.basename(file)
31
+ raise "#{file_name} content is not valid " if delta_config['type'].nil? or delta_config['map_function'].nil?
32
+ Delta.new(id,file_name,delta_config['type'],delta_config['map_function'],delta_config['rollback_function'])
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,60 @@
1
+ module DeployCouch
2
+
3
+ class DeltaProcessor
4
+ def initialize(next_type_version,config,delta,repository)
5
+ @repository = repository
6
+ @delta = delta
7
+ @config = config
8
+ @next_type_version = next_type_version
9
+ end
10
+
11
+ def apply
12
+ user_map_function = @delta.map_function.gsub("\"","\\\"")
13
+ map_function = <<-JSON
14
+ {
15
+ "map":"function(doc){if(doc.#{@config.doc_type_field}=='#{@delta.type}' && (!doc.#{@config.type_version_field} || doc.#{@config.type_version_field} < #{@next_type_version})){new_doc = eval(uneval(doc)); var method = map(new_doc); if(method) emit(method,new_doc);}}
16
+ #{user_map_function}"
17
+ }
18
+ JSON
19
+ modify_document(map_function,@next_type_version)
20
+ end
21
+
22
+ def rollback
23
+ user_rollback_function = @delta.rollback_function.gsub("\"","\\\"")
24
+ current_type_version = @next_type_version - 1
25
+ rollback_function = <<-JSON
26
+ {
27
+ "map":"function(doc){if(doc.#{@config.doc_type_field}=='#{@delta.type}' && (doc.#{@config.type_version_field} >= #{current_type_version})){new_doc = eval(uneval(doc)); var method = map(new_doc); if(method) emit(method,new_doc);}}
28
+ #{user_rollback_function}"
29
+ }
30
+ JSON
31
+ modify_document(rollback_function,current_type_version-1)
32
+ end
33
+
34
+
35
+ private
36
+ def modify_document(function,type_version)
37
+ @repository.get_documents_to_modify(function) do |x|
38
+ update_document(x['value'],type_version) if x['key'] == 'update'
39
+ create_document(x['value'],type_version) if x['key'] == 'create'
40
+ delete_document(x['value'],type_version) if x['key'] == 'delete'
41
+ end
42
+ end
43
+
44
+ def update_document(json_doc,type_version)
45
+ json_doc[@config.type_version_field] = type_version
46
+ @repository.put_document(json_doc)
47
+ end
48
+
49
+ def delete_document(json_doc,type_version)
50
+ @repository.delete_document(json_doc)
51
+ end
52
+
53
+ def create_document(json_doc,type_version)
54
+ json_doc[@config.type_version_field] = type_version
55
+ @repository.post_document(json_doc)
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,70 @@
1
+ module DeployCouch
2
+
3
+ class Deploy
4
+ def initialize(config)
5
+ @config = config
6
+ end
7
+
8
+ def run
9
+ repository = Repository.new(@config)
10
+ delta_loader = DeltaLoader.new(@config.delta_path)
11
+ deltas_map = delta_loader.get_deltas
12
+ couch_schema = DbSchema.load_or_create(@config,repository)
13
+ all_delta_keys = deltas_map.keys.sort
14
+ applied_deltas = couch_schema.applied_deltas.sort
15
+ last_applied_delta_id = 0
16
+ last_applied_delta_id = applied_deltas[-1] if applied_deltas.count > 0
17
+ delta_keys_to_apply = all_delta_keys.select {|key| key > last_applied_delta_id }
18
+
19
+ deltas = []
20
+ puts "Deltas #{all_delta_keys} found"
21
+ puts "Already applied deltas #{applied_deltas}"
22
+ puts "Applying deltas #{delta_keys_to_apply}"
23
+ puts ""
24
+ puts "Start applying deltas"
25
+
26
+ delta_keys_to_apply.each do |key|
27
+ delta = deltas_map[key]
28
+ type = couch_schema.get_next_type_version_for(delta.type)
29
+ DeltaProcessor.new(type,@config,delta,repository).apply
30
+ couch_schema.completed(delta)
31
+ deltas.push(delta)
32
+ puts "applied delta #{delta.file_name}"
33
+ end
34
+
35
+ puts "Finished applying deltas"
36
+ puts ""
37
+ puts "Deltas #{all_delta_keys - applied_deltas - delta_keys_to_apply} where skiped"
38
+
39
+ deltas
40
+ end
41
+
42
+ def rollback
43
+ repository = Repository.new(@config)
44
+ delta_loader = DeltaLoader.new(@config.delta_path)
45
+ deltas_map = delta_loader.get_deltas
46
+ couch_schema = DbSchema.load_or_create(@config,repository)
47
+ applied_deltas = couch_schema.applied_deltas.sort.reverse
48
+
49
+ deltas = []
50
+ puts "Already applied deltas #{applied_deltas}"
51
+ puts "Rolling back deltas #{applied_deltas}"
52
+ puts ""
53
+ puts "Start rolling back deltas"
54
+
55
+ applied_deltas.each do |key|
56
+ delta = deltas_map[key]
57
+ type = couch_schema.get_next_type_version_for(delta.type)
58
+ DeltaProcessor.new(type,@config,delta,repository).rollback
59
+ couch_schema.rollback(delta)
60
+ deltas.push(delta)
61
+ puts "rollback delta #{delta.file_name}"
62
+ end
63
+
64
+ puts "Finished rolling back deltas"
65
+ deltas
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,48 @@
1
+ module DeployCouch
2
+
3
+ class Server
4
+ def initialize(host, port)
5
+ @host = host
6
+ @port = port
7
+ end
8
+
9
+ def delete(uri, options = {:suppress_exceptions=>false})
10
+ request(Net::HTTP::Delete.new(uri),options)
11
+ end
12
+
13
+ def get(uri, options = {:suppress_exceptions=>false})
14
+ request(Net::HTTP::Get.new(uri),options)
15
+ end
16
+
17
+ def put(uri, json, options = {:suppress_exceptions=>false})
18
+ req = Net::HTTP::Put.new(uri)
19
+ req["content-type"] = "application/json"
20
+ req.body = json
21
+ request(req,options)
22
+ end
23
+
24
+ def post(uri, json, options = {:suppress_exceptions=>false})
25
+ req = Net::HTTP::Post.new(uri)
26
+ req["content-type"] = "application/json"
27
+ req.body = json
28
+ request(req,options)
29
+ end
30
+
31
+ def request(req, options)
32
+ res = Net::HTTP.start(@host, @port) { |http|http.request(req) }
33
+ isError = !res.kind_of?(Net::HTTPSuccess)
34
+ shouldSupress = options[:suppress_exceptions]
35
+ if isError and !shouldSupress
36
+ handle_error(req, res)
37
+ end
38
+ res
39
+ end
40
+
41
+ private
42
+
43
+ def handle_error(req, res)
44
+ e = RuntimeError.new("#{res.code}:#{res.message}\nMETHOD:#{req.method}\nURI:#{req.path}\n#{res.body}")
45
+ raise e
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,71 @@
1
+ module DeployCouch
2
+
3
+ class Repository
4
+ PAGE_SIZE = 10
5
+
6
+ def initialize(couch_config)
7
+ @config = couch_config
8
+ end
9
+
10
+ def get_documents(map_function)
11
+ server = Server.new(@config.hostname,@config.port)
12
+ no_of_records = 0
13
+ page_no = 0
14
+ finish_loading_all = false
15
+
16
+ while(!finish_loading_all)
17
+ response = server.post("/#{@config.database}/_temp_view?limit=#{PAGE_SIZE}&skip=#{PAGE_SIZE*page_no}",map_function)
18
+ json = JSON.parse(response.body)
19
+ json["rows"].each do |row|
20
+ yield row
21
+ end
22
+ page_no += 1
23
+ no_of_records += json["rows"].count
24
+ finish_loading_all = true if no_of_records >= json["total_rows"]
25
+ end
26
+ end
27
+
28
+ def get_documents_to_modify(map_function)
29
+ server = Server.new(@config.hostname,@config.port)
30
+ finish_loading_all = false
31
+
32
+ while(!finish_loading_all)
33
+ response = server.post("/#{@config.database}/_temp_view?limit=#{PAGE_SIZE}",map_function)
34
+ json = JSON.parse(response.body)
35
+ json["rows"].each do |row|
36
+ yield row
37
+ end
38
+ finish_loading_all = json["total_rows"] <= 10
39
+ end
40
+ end
41
+
42
+
43
+ def put_document(json)
44
+ server = Server.new(@config.hostname,@config.port)
45
+ server.put("/#{@config.database}/#{json['_id']}",json.to_json)
46
+ end
47
+
48
+ def post_document(json)
49
+ server = Server.new(@config.hostname,@config.port)
50
+ server.post("/#{@config.database}",json.to_json)
51
+ end
52
+
53
+
54
+ def delete_document(json)
55
+ server = Server.new(@config.hostname,@config.port)
56
+ server.delete("/#{@config.database}/#{json['_id']}?rev=#{json['_rev']}")
57
+ end
58
+
59
+ def get_schema
60
+ server = Server.new(@config.hostname,@config.port)
61
+ res = server.get("/#{@config.database}/schema__schema_document_key__",{:suppress_exceptions=>true})
62
+ json = JSON.parse(res.body) if res.kind_of?(Net::HTTPSuccess)
63
+ end
64
+
65
+ def create_schema(json)
66
+ server = Server.new(@config.hostname,@config.port)
67
+ res = server.post("/#{@config.database}/",json.to_json)
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,3 @@
1
+ module DeployCouch
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,13 @@
1
+ require 'json'
2
+ require 'yaml'
3
+ require 'net/http'
4
+
5
+ require 'deploy_couch/version'
6
+ require 'deploy_couch/config'
7
+ require 'deploy_couch/repository'
8
+ require 'deploy_couch/delta_processor'
9
+ require 'deploy_couch/delta_loader'
10
+ require 'deploy_couch/delta'
11
+ require 'deploy_couch/deploy'
12
+ require 'deploy_couch/couch_db_schema'
13
+ require 'deploy_couch/http_client'
data/spec/couchdb.yml ADDED
@@ -0,0 +1,6 @@
1
+ hostname: localhost
2
+ port: 5984
3
+ delta_path: "integration/deltas"
4
+ database: "test"
5
+ doc_type_field: type
6
+ type_version_field: type_version
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ module DeployCouch
4
+ describe Config, "read couch db config" do
5
+ it "should load hostname from couchdb.yml" do
6
+ Config.create_from_file(File.dirname(__FILE__) + '/../couchdb.yml').hostname.should == "localhost"
7
+ end
8
+
9
+ it "should load portnumber from couchdb.yml" do
10
+ Config.create_from_file(File.dirname(__FILE__) + '/../couchdb.yml').port.should == 5984
11
+ end
12
+
13
+ it "should load delta path" do
14
+ Config.create_from_file(File.dirname(__FILE__) + '/../couchdb.yml').delta_path.should == File.dirname(__FILE__) + "/../integration/deltas"
15
+ end
16
+
17
+ it "should load database name" do
18
+ Config.create_from_file(File.dirname(__FILE__) + '/../couchdb.yml').database.should == "test"
19
+ end
20
+
21
+ it "should load document type field" do
22
+ Config.create_from_file(File.dirname(__FILE__) + '/../couchdb.yml').doc_type_field.should == "type"
23
+ end
24
+
25
+ it "should load type version field" do
26
+ Config.create_from_file(File.dirname(__FILE__) + '/../couchdb.yml').type_version_field.should == "type_version"
27
+ end
28
+
29
+
30
+ it "should merge config with passed in values" do
31
+ config = Config.create_from_file(File.dirname(__FILE__) + '/../couchdb.yml')
32
+ config.merge_config("database"=>"db")
33
+ config.database.should == "db"
34
+ end
35
+
36
+ it "should fail with an exception when config file is not found" do
37
+ lambda { Config.create_from_file(File.dirname(__FILE__) + '/../couchdb1.yml') }.should raise_error()
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ module DeployCouch
2
+ class DatabasePopulator
3
+ def initialize(database)
4
+ @database = database
5
+ end
6
+
7
+ def with_type(doc_type)
8
+ @doc_type = doc_type
9
+ self
10
+ end
11
+
12
+ def with_records(no_of_records)
13
+ @no_of_records = no_of_records
14
+ self
15
+ end
16
+
17
+ def with_schema(schema_json)
18
+ @schema = schema_json
19
+ self
20
+ end
21
+
22
+ def build
23
+ server = Server.new("localhost",5984)
24
+ res = server.get("/#{@database}/",{:suppress_exceptions=>true})
25
+ server.delete("/#{@database}/") if res.kind_of?(Net::HTTPSuccess)
26
+ server.put("/#{@database}/","")
27
+ (1..@no_of_records).each do |i|
28
+ h = {"name"=> "name_#{i}","type"=>@doc_type}
29
+ server.post("/#{@database}/",JSON.generate(h))
30
+ end
31
+
32
+ server.post("/#{@database}/",@schema.to_json) if @schema
33
+
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ module DeployCouch
4
+
5
+ describe DeltaLoader, "load all delta" do
6
+
7
+ it "should load all YAML files from the deltas folder" do
8
+
9
+ map_function = "function map(doc) { doc.address = \"some address\"; return 'update'; }"
10
+ rollback_function = "function map(doc) { delete doc.address; return 'update'; }"
11
+
12
+ delta_loader = DeltaLoader.new(File.dirname(__FILE__)+'/deltas')
13
+ deltas = delta_loader.get_deltas
14
+ deltas.count.should == 5
15
+ deltas[1].file_name.should == "1_add_address_to_customer.yml"
16
+ deltas[1].type.should == "customer"
17
+ deltas[1].map_function.should == map_function
18
+ deltas[1].rollback_function.should == rollback_function
19
+ end
20
+
21
+ it "should raise an error when file is not in deltanumber_description format" do
22
+ File.new(File.dirname(__FILE__)+'/deltas/invalid_delta_file.yml','w')
23
+ begin
24
+ delta_loader = DeltaLoader.new(File.dirname(__FILE__)+'/deltas')
25
+ lambda { delta_loader.get_deltas }.should raise_error()
26
+ ensure
27
+ File.delete(File.dirname(__FILE__)+'/deltas/invalid_delta_file.yml')
28
+ end
29
+ end
30
+
31
+ it "should raise an error when two deltas have the same key" do
32
+ File.new(File.dirname(__FILE__)+'/deltas/11_duplicate_key.yml','w')
33
+ begin
34
+ delta_loader = DeltaLoader.new(File.dirname(__FILE__)+'/deltas')
35
+ lambda { delta_loader.get_deltas }.should raise_error()
36
+ ensure
37
+ File.delete(File.dirname(__FILE__)+'/deltas/11_duplicate_key.yml')
38
+ end
39
+
40
+ end
41
+
42
+ it "should raise an error when file content does not have both type and map_function" do
43
+ File.new(File.dirname(__FILE__)+'/deltas/100_invalid_delta_file_content.yml','w')
44
+ begin
45
+ delta_loader = DeltaLoader.new(File.dirname(__FILE__)+'/deltas')
46
+ lambda { delta_loader.get_deltas }.should raise_error()
47
+ ensure
48
+ File.delete(File.dirname(__FILE__)+'/deltas/100_invalid_delta_file_content.yml')
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ end