tsalzer-typesafe 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  = typesafe
2
2
 
3
- Typesafe is a tiny extension to core Ruby to simplify checks for
3
+ TypeSafe is a tiny extension to core Ruby to simplify checks for
4
4
  kind_of?.
5
5
 
6
6
  == Note on Patches/Pull Requests
@@ -10,8 +10,7 @@ kind_of?.
10
10
  * Add tests for it. This is important so I don't break it in a
11
11
  future version unintentionally.
12
12
  * Commit, do not mess with rakefile, version, or history.
13
- (if you want to have your own version, that is fine but
14
- bump version in a commit by itself I can ignore when I pull)
13
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
15
14
  * Send me a pull request. Bonus points for topic branches.
16
15
 
17
16
  == Copyright
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -1,51 +1,67 @@
1
1
  # additional features for all objects
2
2
 
3
- class TypeCheckError < RuntimeError ; end
4
-
3
+ # TypeSafe module.
4
+ # This module will be included into Object to provide Object#must_be_kind_of.
5
+ #
6
+ # Usage
7
+ #
8
+ # If you need e.g. an argument be of a specific type, you can simply write
9
+ #
10
+ # def myfunc(arg)
11
+ # arg.must_be_kind_of(MyFancyClass)
12
+ # arg.do_fancy_stuff
13
+ # end
14
+ #
15
+ # This would raise a TypeError in case you somehow passed in a type not matching
16
+ # your MyFancyClass, which would stop your app dead at a point you know. This is
17
+ # probably better than chasing the wrong parameter all the way down your application.
18
+ #
19
+ # However, being dynamic, you might just need to apply a special treatment to your
20
+ # argument in case it's not what you would expect:
21
+ #
22
+ # def my2ndfunc(arg)
23
+ # puts arg.must_be_kind_of(String) {|x| x.to_s}
24
+ # end
25
+ #
26
+ # In this second case, no exception is raised, but your block is executed. Most
27
+ # important, the return value of your block is returned as value from the method.
28
+ #
5
29
  module TypeSafe
6
- module ObjectTypeChecks
7
- # this object must be kind of a given class.
8
- def must_be_kind_of(clss)
9
- if clss.kind_of?(Module)
10
- raise TypeCheckError.new("#{self} must include module #{clss}") unless self.kind_of?(clss)
11
- elsif clss.kind_of?(Class)
12
- raise TypeCheckError.new("#{self} must be of type #{clss}") unless self.kind_of?(clss)
30
+ # this class or object must be kind of a given class.
31
+ # Method returns <tt>self</tt> unless it raises a TypeError.
32
+ def must_be_kind_of(clss, &blk)
33
+ if clss.kind_of?(Module) or clss.kind_of?(Class)
34
+ matched = if self.kind_of?(Class)
35
+ # classes are expected to "descend" from comparator
36
+ if self != clss
37
+ self.superclass ? self.superclass.must_be_kind_of(clss) : self.kind_of?(clss)
38
+ else
39
+ true
40
+ end
41
+ else
42
+ # objects are expected to implement comparator
43
+ self.kind_of?(clss)
44
+ end
45
+
46
+ unless matched
47
+ if blk
48
+ return yield self.class
49
+ else
50
+ raise TypeError.new("#{self} must be of type #{clss}")
51
+ end
52
+ end
13
53
  else
14
54
  raise "class to check #{self} for must be a Class or Module, but is #{clss}"
15
55
  end
16
- true
56
+ self
17
57
  end
18
58
  alias must_be_a must_be_kind_of
19
59
 
20
- # this object must be kind of a given class.
21
- def must_be_nil_or_kind_of(clss)
22
- self.kind_of?(NilClass) ? true : must_be_kind_of(clss)
60
+ # this class or object must be kind of a given class or nil.
61
+ # This method is probably a bad idea, so it will be removed.
62
+ def must_be_nil_or_kind_of(clss, &blk)
63
+ self.kind_of?(NilClass) ? true : must_be_kind_of(clss, &blk)
23
64
  end
24
-
25
- end#ObjectTypeChecks
26
-
27
- module ClassTypeChecks
28
- # this object must be kind of a given class.
29
- def class_must_be_kind_of(clss)
30
- if clss.kind_of?(Module)
31
- raise TypeCheckError.new("#{self} must include module #{clss}") unless self.kind_of?(clss)
32
- elsif clss.kind_of?(Class)
33
- raise TypeCheckError.new("#{self} must be of type #{clss}") unless self.kind_of?(clss)
34
- else
35
- raise "class to check #{self} for must be a Class or Module, but is #{clss}"
36
- end
37
- true
38
- end
39
- alias class_must_be_a class_must_be_kind_of
40
-
41
- # this object must be kind of a given class.
42
- def must_be_nil_or_kind_of(clss)
43
- self.kind_of?(NilClass) ? true : must_be_kind_of(clss)
44
- end
45
-
46
- end#ClassTypeChecks
47
-
48
- Object.send :include, ObjectTypeChecks
49
- Class.send :include, ClassTypeChecks
50
-
51
65
  end#TypeSafe
66
+
67
+ Object.send :include, TypeSafe
@@ -7,3 +7,24 @@ require 'spec/autorun'
7
7
  Spec::Runner.configure do |config|
8
8
 
9
9
  end
10
+
11
+ # a class hierarchy to check
12
+
13
+ # plain module
14
+ module ModA
15
+ end
16
+ # plain class
17
+ class ClassA
18
+ end
19
+ # class derived from ClassA
20
+ class ClassB < ClassA
21
+ end
22
+ # plain class, extends module ModA, thereby descending ModA
23
+ class ClassC
24
+ extend ModA
25
+ end
26
+ # plain class, includes module ModA, thereby not descending ModA
27
+ class Classd
28
+ include ModA
29
+ end
30
+
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe TypeSafe, ".must_be_kind_of" do
4
+ it "should recognize Class as kind of Object" do
5
+ lambda{Class.must_be_kind_of(Object)}.should_not raise_error(TypeError)
6
+ end
7
+ it "should recognize Object as kind of Class" do
8
+ lambda{Object.must_be_kind_of(Class)}.should_not raise_error(TypeError)
9
+ end
10
+ it "should recognize Fixnum as kind of Integer" do
11
+ lambda{Fixnum.must_be_kind_of(Integer)}.should_not raise_error(TypeError)
12
+ end
13
+ it "should recognize Bignum as kind of Integer" do
14
+ lambda{Bignum.must_be_kind_of(Integer)}.should_not raise_error(TypeError)
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe TypeSafe, ".must_be_kind_of" do
4
+ it "should recognize ClassA as kind of Object" do
5
+ lambda{ClassA.must_be_kind_of(Object)}.should_not raise_error(TypeError)
6
+ end
7
+ it "should recognize ClassB as kind of ClassA" do
8
+ lambda{ClassB.must_be_kind_of(ClassA)}.should_not raise_error(TypeError)
9
+ end
10
+ it "should not recognize ClassC as kind of ClassA" do
11
+ lambda{ClassC.must_be_kind_of(ClassA)}.should raise_error(TypeError)
12
+ end
13
+ it "should not recognize ClassC as kind of ModA" do
14
+ lambda{ClassC.must_be_kind_of(ModA)}.should raise_error(TypeError)
15
+ end
16
+ it "should recognize ClassD as kind of ModA" do
17
+ lambda{ClassD.must_be_kind_of(ModA)}.should_not raise_error(TypeError)
18
+ end
19
+ end
@@ -6,21 +6,46 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
6
6
  Object.new.should respond_to(method)
7
7
  end
8
8
  it "should recognize a simple type" do
9
- lambda{1.send method, Fixnum}.should_not raise_error(TypeCheckError)
9
+ lambda{1.send method, Fixnum}.should_not raise_error(TypeError)
10
10
  end
11
11
  it "should recognize parent classes" do
12
- lambda{self.send method, Object}.should_not raise_error(TypeCheckError)
12
+ lambda{self.send method, Object}.should_not raise_error(TypeError)
13
13
  end
14
- it "should raise a TypeCheckError for mismatching types" do
15
- lambda{"1".send method, Fixnum}.should raise_error(TypeCheckError)
14
+ it "should raise a TypeError for mismatching types" do
15
+ lambda{"1".send method, Fixnum}.should raise_error(TypeError)
16
16
  end
17
+ it "should not raise a TypeError for mismatching types if a block was given" do
18
+ lambda{"1".send method, Fixnum do |clss|
19
+ clss.should be_a Class
20
+ clss.should == String
21
+ end}.should_not raise_error(TypeError)
22
+ end
23
+ it "should execute the given block for mismatching types" do
24
+ executed = false
25
+ lambda{"1".send method, Fixnum do |clss|
26
+ clss.should be_a Class
27
+ clss.should == String
28
+ executed = true
29
+ end}.should_not raise_error(TypeError)
30
+ executed.should == true
31
+ end
32
+ it "should not execute the given block for matching types" do
33
+ executed = false
34
+ lambda{1.send method, Fixnum do |clss|
35
+ clss.should be_a Class
36
+ clss.should == Fixnum
37
+ executed = true
38
+ end}.should_not raise_error(TypeError)
39
+ executed.should == false
40
+ end
41
+
17
42
  it "should raise a RuntimeError if the given match is not a Class" do
18
43
  lambda{"1".send method, "Fixnum"}.should raise_error(RuntimeError)
19
- lambda{"1".send method, "Fixnum"}.should_not raise_error(TypeCheckError)
44
+ lambda{"1".send method, "Fixnum"}.should_not raise_error(TypeError)
20
45
  end
21
46
 
22
- it "should #{nil_allowed ? 'not ' : ''}raise a TypeCheckError for mismatching types on nil" do
23
- lambda{nil.send method, Fixnum}.send nil_allowed ? :should_not : :should, raise_error(TypeCheckError)
47
+ it "should #{nil_allowed ? 'not ' : ''}raise a TypeError for mismatching types on nil" do
48
+ lambda{nil.send method, Fixnum}.send nil_allowed ? :should_not : :should, raise_error(TypeError)
24
49
  end
25
50
 
26
51
  it "should recognize included modules" do
@@ -29,7 +54,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
29
54
  include TestModule
30
55
  end
31
56
  o = TestClass.new
32
- lambda{o.send method, TestModule}.should_not raise_error(TypeCheckError)
57
+ lambda{o.send method, TestModule}.should_not raise_error(TypeError)
33
58
  end
34
59
  end
35
60
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{typesafe}
8
- s.version = "0.0.0"
8
+ s.version = "0.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Till Salzer"]
12
- s.date = %q{2009-08-24}
12
+ s.date = %q{2009-08-26}
13
13
  s.description = %q{Simplifies typesafe development by providing the additional
14
14
  methods Object#must_by_kind_of ad Object#must_be_a.}
15
15
  s.email = %q{till.salzer@googlemail.com}
@@ -29,17 +29,20 @@ Gem::Specification.new do |s|
29
29
  "features/typesafe.feature",
30
30
  "lib/typesafe.rb",
31
31
  "spec/spec_helper.rb",
32
+ "spec/typesafe_class_coreclasses_spec.rb",
33
+ "spec/typesafe_class_spec.rb",
32
34
  "spec/typesafe_spec.rb",
33
35
  "typesafe.gemspec"
34
36
  ]
35
- s.has_rdoc = true
36
37
  s.homepage = %q{http://github.com/tsalzer/typesafe}
37
38
  s.rdoc_options = ["--charset=UTF-8"]
38
39
  s.require_paths = ["lib"]
39
- s.rubygems_version = %q{1.3.2}
40
+ s.rubygems_version = %q{1.3.5}
40
41
  s.summary = %q{provides Object#must_be_kind_of for typesafe development}
41
42
  s.test_files = [
42
43
  "spec/spec_helper.rb",
44
+ "spec/typesafe_class_coreclasses_spec.rb",
45
+ "spec/typesafe_class_spec.rb",
43
46
  "spec/typesafe_spec.rb"
44
47
  ]
45
48
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tsalzer-typesafe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Till Salzer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-24 00:00:00 -07:00
12
+ date: 2009-08-26 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -53,9 +53,11 @@ files:
53
53
  - features/typesafe.feature
54
54
  - lib/typesafe.rb
55
55
  - spec/spec_helper.rb
56
+ - spec/typesafe_class_coreclasses_spec.rb
57
+ - spec/typesafe_class_spec.rb
56
58
  - spec/typesafe_spec.rb
57
59
  - typesafe.gemspec
58
- has_rdoc: true
60
+ has_rdoc: false
59
61
  homepage: http://github.com/tsalzer/typesafe
60
62
  licenses:
61
63
  post_install_message:
@@ -84,4 +86,6 @@ specification_version: 3
84
86
  summary: provides Object#must_be_kind_of for typesafe development
85
87
  test_files:
86
88
  - spec/spec_helper.rb
89
+ - spec/typesafe_class_coreclasses_spec.rb
90
+ - spec/typesafe_class_spec.rb
87
91
  - spec/typesafe_spec.rb