From 2818b09c877cc726b6efde91b69d624074c65a3f Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Wed, 18 Jun 2008 01:17:51 +0000 Subject: [PATCH] rb: Add helpers for optional type-checking git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@669013 13f79535-47bb-0310-9956-ffa450edef68 --- lib/rb/lib/thrift/types.rb | 44 +++++++++++++++++++++++++++++++ lib/rb/spec/types_spec.rb | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 lib/rb/spec/types_spec.rb diff --git a/lib/rb/lib/thrift/types.rb b/lib/rb/lib/thrift/types.rb index 237df3ca..bc091957 100644 --- a/lib/rb/lib/thrift/types.rb +++ b/lib/rb/lib/thrift/types.rb @@ -1,3 +1,5 @@ +require 'set' + module Thrift module Types STOP = 0 @@ -16,6 +18,46 @@ module Thrift end deprecate_module! :TType => Types + class << self + attr_accessor :type_checking + end + + class TypeError < Exception + end + + def self.check_type(value, type) + return unless Thrift.type_checking + klasses = case type + when Types::VOID + NilClass + when Types::BOOL + [TrueClass, FalseClass] + when Types::BYTE, Types::I16, Types::I32, Types::I64 + Integer + when Types::DOUBLE + Float + when Types::STRING + String + when Types::STRUCT + Struct + when Types::MAP + Hash + when Types::SET + Set + when Types::LIST + Array + end + valid = klasses && [*klasses].any? { |klass| klass === value } + raise TypeError, "Expected #{type_name(type)}, received #{value.class}" unless valid + end + + def self.type_name(type) + Types.constants.each do |const| + return "Types::#{const}" if Types.const_get(const) == type + end + nil + end + module MessageTypes CALL = 1 REPLY = 2 @@ -23,3 +65,5 @@ module Thrift end deprecate_module! :TMessageType => MessageTypes end + +Thrift.type_checking = false if Thrift.type_checking.nil? diff --git a/lib/rb/spec/types_spec.rb b/lib/rb/spec/types_spec.rb new file mode 100644 index 00000000..d40e492b --- /dev/null +++ b/lib/rb/spec/types_spec.rb @@ -0,0 +1,54 @@ +require File.dirname(__FILE__) + '/spec_helper' +$:.unshift File.dirname(__FILE__) + "/gen-rb" +require 'ThriftSpec_types' + +class ThriftTypesSpec < Spec::ExampleGroup + include Thrift + + describe "Type checking" do + it "should return the proper name for each type" do + Thrift.type_name(Types::I16).should == "Types::I16" + Thrift.type_name(Types::VOID).should == "Types::VOID" + Thrift.type_name(Types::LIST).should == "Types::LIST" + Thrift.type_name(42).should be_nil + end + + it "should check types properly" do + Thrift.type_checking = true + begin + lambda { Thrift.check_type(nil, Types::STOP) }.should raise_error(TypeError) + lambda { Thrift.check_type(nil, Types::VOID) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(3, Types::VOID) }.should raise_error(TypeError) + lambda { Thrift.check_type(true, Types::BOOL) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(3, Types::BOOL) }.should raise_error(TypeError) + lambda { Thrift.check_type(nil, Types::BOOL) }.should raise_error(TypeError) + lambda { Thrift.check_type(42, Types::BYTE) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(42, Types::I16) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(42, Types::I32) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(42, Types::I64) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(3.14, Types::I32) }.should raise_error(TypeError) + lambda { Thrift.check_type(3.14, Types::DOUBLE) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(3, Types::DOUBLE) }.should raise_error(TypeError) + lambda { Thrift.check_type("3", Types::STRING) }.should_not raise_error(TypeError) + lambda { Thrift.check_type(3, Types::STRING) }.should raise_error(TypeError) + hello = SpecNamespace::Hello.new + lambda { Thrift.check_type(hello, Types::STRUCT) }.should_not raise_error(TypeError) + lambda { Thrift.check_type("foo", Types::STRUCT) }.should raise_error(TypeError) + lambda { Thrift.check_type({:foo => 1}, Types::MAP) }.should_not raise_error(TypeError) + lambda { Thrift.check_type([1], Types::MAP) }.should raise_error(TypeError) + lambda { Thrift.check_type([1], Types::LIST) }.should_not raise_error(TypeError) + lambda { Thrift.check_type({:foo => 1}, Types::LIST) }.should raise_error(TypeError) + lambda { Thrift.check_type(Set.new([1,2]), Types::SET) }.should_not raise_error(TypeError) + lambda { Thrift.check_type([1,2], Types::SET) }.should raise_error(TypeError) + lambda { Thrift.check_type({:foo => true}, Types::SET) }.should raise_error(TypeError) + ensure + Thrift.type_checking = false + end + end + + it "should be disabled when Thrift.type_checking = false" do + Thrift.type_checking = false + lambda { Thrift.check_type(3, Types::STRING) }.should_not raise_error(TypeError) + end + end +end -- 2.17.1