schemata-router 0.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ module Schemata
2
+ module HashCopyHelpers
3
+ class CopyError < StandardError; end
4
+
5
+ def self.deep_copy(node)
6
+ case node
7
+ when String
8
+ return node.dup
9
+ when Numeric, TrueClass, FalseClass
10
+ return node
11
+ when Hash
12
+ copy = {}
13
+ # XXX NB: The 'to_s' below was included because some components use
14
+ # symbols as keys instead of strings. This fix is temporary; in the
15
+ # long term, we should change all components to use the same type for
16
+ # their keys
17
+ node.each { |k, v| copy[k.to_s] = deep_copy(v) }
18
+ return copy
19
+ when Array
20
+ return node.map { |v| deep_copy(v) }
21
+ when NilClass
22
+ return nil
23
+ else
24
+ raise CopyError.new("Unexpected class: #{node.class}")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ module Schemata
2
+ module HashCopyHelpers
3
+
4
+ def self.stringify(node)
5
+ case node
6
+ when String
7
+ return node
8
+ when Numeric, TrueClass, FalseClass
9
+ return node
10
+ when Hash
11
+ copy = {}
12
+ node.each { |k, v| copy[k.to_s] = stringify(v) }
13
+ return copy
14
+ when Array
15
+ return node.map { |v| stringify(v) }
16
+ when NilClass
17
+ return nil
18
+ when Symbol
19
+ return node.to_s
20
+ else
21
+ raise CopyError.new("Unexpected class: #{node.class}")
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ require 'schemata/router/register_request'
2
+ require 'schemata/router/start_message'
3
+
4
+ module Schemata
5
+ module Router
6
+ def self.mock_register_request(version=RegisterRequest.current_version)
7
+ RegisterRequest::const_get("V#{version}").mock
8
+ end
9
+
10
+ def self.mock_start_message(version=StartMessage.current_version)
11
+ StartMessage::const_get("V#{version}").mock
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'schemata/common/msgtypebase'
2
+
3
+ module Schemata
4
+ module Router
5
+ module RegisterRequest
6
+ extend Schemata::MessageTypeBase
7
+ end
8
+ end
9
+ end
10
+
11
+ Dir[File.dirname(__FILE__) + '/register_request/*.rb'].each do |file|
12
+ require file
13
+ end
@@ -0,0 +1,53 @@
1
+ #require 'vcap/common'
2
+
3
+ module Schemata
4
+ module Router
5
+ module RegisterRequest
6
+ version 1 do
7
+ include_preschemata
8
+
9
+ define_schema do
10
+ {
11
+ optional("dea") => String,
12
+ optional("app") => String,
13
+ "uris" => [String],
14
+ "host" => String,
15
+ "port" => Integer,
16
+ "tags" => {
17
+ optional("framework") => String,
18
+ optional("runtime") => String,
19
+ optional("component") => String,
20
+ },
21
+ optional("private_instance_id") => String,
22
+ }
23
+ end
24
+
25
+ define_min_version 1
26
+
27
+ define_upvert do |old_data|
28
+ raise NotImplementedError.new
29
+ end
30
+
31
+ define_generate_old_fields do |msg_obj|
32
+ raise NotImplementedError.new
33
+ end
34
+
35
+ define_mock_values do
36
+ {
37
+ "dea" => "deadbeef", #proc { VCAP.secure_uuid },
38
+ "app" => proc { Random.rand(100).to_s },
39
+ "uris" => ["foo.vcap.me"],
40
+ "host" => "127.0.0.1",
41
+ "port" => 80,
42
+ "tags" => {
43
+ "framework" => "rails3",
44
+ "runtime" => "ruby18",
45
+ "component" => "dashboard",
46
+ },
47
+ "private_instance_id" => "deadbeef1",#proc { VCAP.secure_uuid },
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,13 @@
1
+ require 'schemata/common/msgtypebase'
2
+
3
+ module Schemata
4
+ module Router
5
+ module StartMessage
6
+ extend Schemata::MessageTypeBase
7
+ end
8
+ end
9
+ end
10
+
11
+ Dir[File.dirname(__FILE__) + '/start_message/*.rb'].each do |file|
12
+ require file
13
+ end
@@ -0,0 +1,35 @@
1
+ #require "vcap/common"
2
+
3
+ module Schemata
4
+ module Router
5
+ module StartMessage
6
+ version 1 do
7
+ include_preschemata
8
+
9
+ define_schema do
10
+ {
11
+ "id" => String,
12
+ "version" => String,
13
+ }
14
+ end
15
+
16
+ define_min_version 1
17
+
18
+ define_upvert do |old_data|
19
+ raise NotImplmenetedError.new
20
+ end
21
+
22
+ define_generate_old_fields do |msg_obj|
23
+ raise NotImplementedError.new
24
+ end
25
+
26
+ define_mock_values do
27
+ {
28
+ "id" => "deadbeef", #proc { VCAP.secure_uuid },
29
+ "version" => "0.1.0",
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ module Schemata
2
+ module Router
3
+ VERSION = "0.0.1.beta1"
4
+ end
5
+ end
@@ -0,0 +1,115 @@
1
+ require 'schemata/helpers/hash_copy'
2
+ require 'schemata/helpers/stringify'
3
+
4
+ describe Schemata::HashCopyHelpers do
5
+ describe "#deep_copy" do
6
+ it "should deep copy nil" do
7
+ copy = Schemata::HashCopyHelpers.deep_copy(nil)
8
+ copy.should == nil
9
+ end
10
+
11
+ it "should deep copy a given string" do
12
+ original = "foo"
13
+ copy = Schemata::HashCopyHelpers.deep_copy(original)
14
+ copy.should be_instance_of String
15
+ copy.should == original
16
+ copy.object_id.should_not == original.object_id
17
+ end
18
+
19
+ it "should deep copy a given boolean" do
20
+ Schemata::HashCopyHelpers.deep_copy(true).
21
+ should be_an_instance_of TrueClass
22
+ Schemata::HashCopyHelpers.deep_copy(false).
23
+ should be_an_instance_of FalseClass
24
+ end
25
+
26
+ it "should deep copy a given numeric type" do
27
+ original = 0
28
+ copy = Schemata::HashCopyHelpers.deep_copy(original)
29
+ copy.should == original
30
+ copy.should be_an_instance_of Fixnum
31
+
32
+ # set original to be max fixnum + 1
33
+ original = 2**(0.size * 8 - 2)
34
+ copy = Schemata::HashCopyHelpers.deep_copy(original)
35
+ copy.should == original
36
+ copy.should be_an_instance_of Bignum
37
+
38
+ original = 0.0
39
+ copy = Schemata::HashCopyHelpers.deep_copy(original)
40
+ copy.should == original
41
+ copy.should be_an_instance_of Float
42
+ end
43
+
44
+ it "should deep copy a given hash" do
45
+ original = {"foo" => "bar"}
46
+ copy = Schemata::HashCopyHelpers.deep_copy(original)
47
+ copy.should be_instance_of Hash
48
+ copy.should == original
49
+
50
+ copy.object_id.should_not == original.object_id
51
+ copy["foo"].object_id.should_not == original["foo"].object_id
52
+ end
53
+
54
+ it "should deep copy a given array" do
55
+ original = [1, 2, "hello"]
56
+ copy = Schemata::HashCopyHelpers.deep_copy(original)
57
+ copy.should be_instance_of Array
58
+ copy.should == original
59
+
60
+ copy.object_id.should_not == original.object_id
61
+ # only check object_id of String object
62
+ copy[2].object_id.should_not == original[2].object_id
63
+ end
64
+
65
+ it "should deep copy nested types" do
66
+ original = {
67
+ "foo" => "bar",
68
+ "inner" => {
69
+ "hello" => "goodbye",
70
+ },
71
+ }
72
+ copy = Schemata::HashCopyHelpers.deep_copy(original)
73
+ copy.should be_instance_of Hash
74
+ copy.should == original
75
+
76
+ copy.object_id.should_not == original.object_id
77
+ copy["foo"].object_id.should_not == original["foo"].object_id
78
+ copy["inner"].object_id.should_not == original["inner"].object_id
79
+ copy["inner"]["hello"].object_id.
80
+ should_not == original["inner"]["hello"].object_id
81
+ end
82
+
83
+ it "should raise error for unknown type" do
84
+ klass = Class.new
85
+ expect do
86
+ Schemata::HashCopyHelpers.deep_copy(klass.new)
87
+ end.to raise_error(described_class::CopyError, /Unexpected class: /)
88
+ end
89
+ end
90
+
91
+ describe "#stringify" do
92
+ it "should stringify nil" do
93
+ str = Schemata::HashCopyHelpers.stringify(nil)
94
+ str.should == nil
95
+ end
96
+
97
+ it "should stringify a string" do
98
+ original = "foo"
99
+ str = Schemata::HashCopyHelpers.stringify(original)
100
+ str.should == "foo"
101
+ end
102
+
103
+ it "should stringify a symbol" do
104
+ original = :foo
105
+ str = Schemata::HashCopyHelpers.stringify(original)
106
+ str.should == "foo"
107
+ end
108
+
109
+ it "should stringify a hash" do
110
+ original = { "foo" => :foo }
111
+ str = Schemata::HashCopyHelpers.stringify(original)
112
+ str.should == { "foo" => "foo" }
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,46 @@
1
+ require 'schemata/common/parsed_msg'
2
+
3
+ describe Schemata::ParsedMessage do
4
+ describe "#new" do
5
+ it "should raise an error if 'min_version' is missing" do
6
+ json = '{
7
+ "V10" : { "foo" : "bar" }
8
+ }'
9
+ expect {
10
+ msg = Schemata::ParsedMessage.new(json)
11
+ }.to raise_error(Schemata::DecodeError)
12
+ end
13
+
14
+ it "should raise an error if there are non-Vxx hashes" do
15
+ json = '{
16
+ "min_version" : 10,
17
+ "foo" : "bar"
18
+ }'
19
+ expect {
20
+ msg = Schemata::ParsedMessage.new(json)
21
+ }.to raise_error(Schemata::DecodeError)
22
+ end
23
+
24
+ it "should raise an error if there are no Vxx hashes" do
25
+ json = '{
26
+ "min_version" : 10
27
+ }'
28
+ expect {
29
+ msg = Schemata::ParsedMessage.new(json)
30
+ }.to raise_error(Schemata::DecodeError)
31
+ end
32
+
33
+ it "should return a new Schemata::ParsedMessage if the hash is valid" do
34
+ json = '{
35
+ "min_version" : 10,
36
+ "V10" : { "foo" : "bar" },
37
+ "V11" : { "foo" : "bar"}
38
+ }'
39
+ msg = Schemata::ParsedMessage.new(json)
40
+ msg.min_version.should == 10
41
+ msg.version.should == 11
42
+ msg.contents["V10"]["foo"].should == "bar"
43
+ msg.contents["V11"]["foo"].should == "bar"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ require 'schemata/router'
2
+ require 'spec_helper'
3
+
4
+ describe Schemata::Router::RegisterRequest do
5
+ it_behaves_like "a message type"
6
+ end
7
+
8
+ describe Schemata::Router::RegisterRequest::V1 do
9
+ it_behaves_like "a message"
10
+ end
@@ -0,0 +1,6 @@
1
+ require 'schemata/router'
2
+ require 'spec_helper'
3
+
4
+ describe Schemata::Router do
5
+ it_behaves_like "a schemata component"
6
+ end
@@ -0,0 +1,10 @@
1
+ require 'schemata/router'
2
+ require 'spec_helper'
3
+
4
+ describe Schemata::Router::StartMessage do
5
+ it_behaves_like "a message type"
6
+ end
7
+
8
+ describe Schemata::Router::StartMessage::V1 do
9
+ it_behaves_like "a message"
10
+ end
@@ -0,0 +1 @@
1
+ Dir["./spec/support/**/*.rb"].sort.each { |f| require f }
@@ -0,0 +1,51 @@
1
+ require 'support/helpers'
2
+
3
+ shared_examples "a schemata component" do
4
+
5
+ described_class.constants.select { |x| x != :VERSION }.each do |msg_type|
6
+ describe ".mock_#{decamelize(msg_type.to_s)}" do
7
+ versions = described_class::const_get(msg_type).constants.select { |x| x =~ /V[0-9]+/ }
8
+ versions.map { |x| x = x.to_s[1..-1].to_i }.each do |version|
9
+ it_behaves_like "a mocking method", version do
10
+ let(:message_type) { described_class::const_get(msg_type) }
11
+ let(:message_type_name) { msg_type.to_s }
12
+ let(:component) { described_class }
13
+ let(:component_name) { component.name.split("::")[1] }
14
+
15
+ let(:mock_method) { "mock_#{decamelize(msg_type)}"}
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ shared_examples "a mocking method" do |version|
23
+
24
+ context "when current_version is #{version}" do
25
+ before :each do
26
+ set_current_version(message_type, version)
27
+ end
28
+
29
+ after :each do
30
+ reset_version(message_type)
31
+ end
32
+
33
+ it "should return a V#{version} object if called with no argument" do
34
+ msg_obj = component.send(mock_method)
35
+ msg_obj.class.should == message_type::const_get("V#{version}")
36
+ end
37
+
38
+ 1.upto(version) do |i|
39
+ it "should return a V#{i} object if called with input #{i}" do
40
+ msg_obj = component.send(mock_method, i)
41
+ msg_obj.class.should == message_type::const_get("V#{i}")
42
+ end
43
+ end
44
+
45
+ it "should raise an error if called with input > #{version}" do
46
+ expect {
47
+ msg_obj = component.send(mock_method, version + 1)
48
+ }.to raise_error(NameError)
49
+ end
50
+ end
51
+ end