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.
- data/lib/schemata/common/error.rb +12 -0
- data/lib/schemata/common/msgbase.rb +281 -0
- data/lib/schemata/common/msgtypebase.rb +144 -0
- data/lib/schemata/common/parsed_msg.rb +43 -0
- data/lib/schemata/helpers/hash_copy.rb +28 -0
- data/lib/schemata/helpers/stringify.rb +26 -0
- data/lib/schemata/router.rb +14 -0
- data/lib/schemata/router/register_request.rb +13 -0
- data/lib/schemata/router/register_request/register_request_v1.rb +53 -0
- data/lib/schemata/router/start_message.rb +13 -0
- data/lib/schemata/router/start_message/start_message_v1.rb +35 -0
- data/lib/schemata/router/version.rb +5 -0
- data/spec/common/helpers_spec.rb +115 -0
- data/spec/common/parsed_msg_spec.rb +46 -0
- data/spec/router/register_request_spec.rb +10 -0
- data/spec/router/router_spec.rb +6 -0
- data/spec/router/start_message_spec.rb +10 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/component_helpers.rb +51 -0
- data/spec/support/helpers.rb +54 -0
- data/spec/support/message_helpers.rb +138 -0
- data/spec/support/message_type_helpers.rb +171 -0
- metadata +158 -0
| @@ -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,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,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,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
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -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
         |