schemata-router 0.0.1.beta1

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.
@@ -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