You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by kc...@apache.org on 2008/06/18 03:17:52 UTC

svn commit: r669013 - in /incubator/thrift/trunk/lib/rb: lib/thrift/types.rb spec/types_spec.rb

Author: kclark
Date: Tue Jun 17 18:17:51 2008
New Revision: 669013

URL: http://svn.apache.org/viewvc?rev=669013&view=rev
Log:
rb: Add helpers for optional type-checking

Added:
    incubator/thrift/trunk/lib/rb/spec/types_spec.rb
Modified:
    incubator/thrift/trunk/lib/rb/lib/thrift/types.rb

Modified: incubator/thrift/trunk/lib/rb/lib/thrift/types.rb
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/rb/lib/thrift/types.rb?rev=669013&r1=669012&r2=669013&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/rb/lib/thrift/types.rb (original)
+++ incubator/thrift/trunk/lib/rb/lib/thrift/types.rb Tue Jun 17 18:17:51 2008
@@ -1,3 +1,5 @@
+require 'set'
+
 module Thrift
   module Types
     STOP = 0
@@ -16,6 +18,46 @@
   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 @@
   end
   deprecate_module! :TMessageType => MessageTypes
 end
+
+Thrift.type_checking = false if Thrift.type_checking.nil?

Added: incubator/thrift/trunk/lib/rb/spec/types_spec.rb
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/rb/spec/types_spec.rb?rev=669013&view=auto
==============================================================================
--- incubator/thrift/trunk/lib/rb/spec/types_spec.rb (added)
+++ incubator/thrift/trunk/lib/rb/spec/types_spec.rb Tue Jun 17 18:17:51 2008
@@ -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