must 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -10,9 +10,14 @@ add Object#must method to constrain its origin and conversions
10
10
  num = params[:num].to_i
11
11
  num = 10 unless (1..300) === num
12
12
 
13
+ and has duck features
13
14
 
14
- Testing Methods
15
- ===============
15
+ 1.must.duck?(:to_s) # => true
16
+ io.must.duck(:write) { io.extend Writable }
17
+
18
+
19
+ Asking Methods
20
+ ==============
16
21
 
17
22
  be : check whether object equals to the argument
18
23
  kind_of : check whether object is a kind of the arguments
@@ -36,6 +41,15 @@ an : return self
36
41
  These effect nothing but exist only for English grammar.
37
42
 
38
43
 
44
+ Duck Methods
45
+ ============
46
+ duck("foo") : check whether object responds to "foo" method.
47
+ duck(:foo) : same above
48
+ duck(".foo") : same above
49
+ duck("#foo") : check whether object has "foo" instance method. (tested only in class/module)
50
+ duck?(...) : acts same as "duck", but this returns a just boolean
51
+
52
+
39
53
  Basic Examples
40
54
  ==============
41
55
 
@@ -114,8 +128,7 @@ Actual Examples
114
128
  Install
115
129
  =======
116
130
 
117
- gem install maiha-must
118
- # add source http://gems.github.com
131
+ gem install must
119
132
 
120
133
  % irb -r rubygems -r must
121
134
  irb(main):001:0> 1.must.be 1
data/lib/must/rule.rb CHANGED
@@ -48,6 +48,7 @@ module Must
48
48
  def one_of(target, &block)
49
49
  valid?(target === @object, &block)
50
50
  end
51
+ alias :match :one_of
51
52
 
52
53
  def valid?(condition, &block)
53
54
  if condition ^ @not
@@ -81,6 +82,31 @@ module Must
81
82
  retry
82
83
  end
83
84
 
84
- alias :match :one_of
85
+ def duck(method_name, &block)
86
+ valid?(duck?(method_name), &block)
87
+ end
88
+
89
+ def duck?(method_name)
90
+ case method_name.to_s
91
+ when /^\./ then method_defined?($')
92
+ when /^#/ then instance_method_defined?($')
93
+ else ; method_defined?(method_name)
94
+ end
95
+ end
96
+
97
+ private
98
+ def instance?
99
+ @object.class.to_s !~ /\A(Class|Module)\Z/o
100
+ end
101
+
102
+ def instance_method_defined?(method_name)
103
+ return false if instance?
104
+ !! @object.instance_methods.find { |m| m.to_s == method_name.to_s}
105
+ end
106
+
107
+ def method_defined?(method_name)
108
+ @object.respond_to?(method_name)
109
+ end
110
+
85
111
  end
86
112
  end
@@ -0,0 +1,3 @@
1
+ module Must
2
+ VERSION = "0.2.3"
3
+ end
data/lib/must.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "must/version"
2
+
1
3
  # Must
2
4
  module Must
3
5
  class Invalid < StandardError; end
@@ -12,5 +14,5 @@ module Must
12
14
  end
13
15
  end
14
16
 
15
- require File.dirname(__FILE__) + '/must/rule'
17
+ require "must/rule"
16
18
  Object.__send__ :include, Must
data/must.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "must/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "must"
7
+ s.version = Must::VERSION
8
+ s.authors = ["maiha"]
9
+ s.email = ["maiha@wota.jp"]
10
+ s.homepage = "http://github.com/maiha/must"
11
+ s.summary = %q{a runtime specification tool}
12
+ s.description = %q{add Object#must method to constrain its origin and conversions}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ # specify any dependencies here; for example:
20
+ # s.add_development_dependency "rspec"
21
+ # s.add_runtime_dependency "rest-client"
22
+ end
@@ -0,0 +1,39 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require File.join(File.dirname(__FILE__), '../init')
4
+
5
+ class CoercedTest < Test::Unit::TestCase
6
+ def test_is_a_feature
7
+ assert_equal 1, 1.must.be.coerced(Integer)
8
+ assert_equal 1, 1.must.be.coerced(Integer, String)
9
+ assert_equal 1, 1.must.be.coerced(String, Numeric)
10
+
11
+ assert_raises(Invalid) { "1".must.be.coerced(Integer) }
12
+ assert_raises(Invalid) { "1".must.be.coerced(Integer, Range) }
13
+ assert_raises(NotImplementedError) { "1".must.be.coerced(Integer){raise NotImplementedError} }
14
+ end
15
+
16
+ def test_coecing_succeeded
17
+ assert_equal 1, 1.must.be.coerced(Integer, String=>proc{|i|i.to_i})
18
+ assert_equal 1, "1".must.be.coerced(Integer, String=>proc{|i|i.to_i})
19
+ assert_equal 1, "1".must.be.coerced(Integer, String=>proc{|i|i.to_i}, Range=>proc{|i|i.first})
20
+ assert_equal 1, "1".must.be.coerced(Integer, Range, String=>proc{|i|i.to_i}, Range=>proc{|i|i.first})
21
+ assert_equal 1, "1".must.be.coerced(File, Integer, Range, String=>proc{|i|i.to_i}, Range=>proc{|i|i.first})
22
+ end
23
+
24
+ def test_coecing_failed
25
+ assert_raises(Invalid) { "1".must.be.coerced(Integer, String=>proc{|i| /a/}) }
26
+ assert_raises(NotImplementedError) { "1".must.be.coerced(Integer, String=>proc{|i| /a/}){raise NotImplementedError} }
27
+ end
28
+
29
+ def test_cascaded_coecing_succeeded
30
+ assert_equal 1, 1.must.be.coerced(Integer, Symbol=>:to_s, String=>:to_i)
31
+ assert_equal 1, "1".must.be.coerced(Integer, Symbol=>:to_s, String=>:to_i)
32
+ assert_equal 1, :"1".must.be.coerced(Integer, Symbol=>:to_s, String=>:to_i)
33
+ end
34
+
35
+ def test_detect_livelock
36
+ assert_raises(Invalid){ "1".must.be.coerced(Integer, Symbol=>:to_s, String=>:intern)}
37
+ assert_raises(Invalid){:"1".must.be.coerced(Integer, Symbol=>:to_s, String=>:intern)}
38
+ end
39
+ end
data/test/duck_test.rb ADDED
@@ -0,0 +1,83 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require File.join(File.dirname(__FILE__), '../init')
4
+
5
+ class DuckTest < Test::Unit::TestCase
6
+ class ClassFoo
7
+ def foo; 1; end
8
+ end
9
+
10
+ module ModuleFoo
11
+ def foo; 1; end
12
+ end
13
+
14
+ def test_itself_duck_type
15
+ # succeeded
16
+ assert_equal 1, 1.must.duck(:to_s)
17
+ assert_equal 1, 1.must.duck("to_s")
18
+ assert_equal 1, 1.must.duck(".to_s")
19
+ assert_equal ClassFoo, ClassFoo.must.duck(:to_s)
20
+ assert_equal ClassFoo, ClassFoo.must.duck("to_s")
21
+ assert_equal ClassFoo, ClassFoo.must.duck(".to_s")
22
+ assert_equal ModuleFoo, ModuleFoo.must.duck(:to_s)
23
+ assert_equal ModuleFoo, ModuleFoo.must.duck("to_s")
24
+ assert_equal ModuleFoo, ModuleFoo.must.duck(".to_s")
25
+
26
+ # failed
27
+ assert_raises(Invalid) { 1.must.duck(:foo) }
28
+ assert_raises(Invalid) { 1.must.duck("foo") }
29
+ assert_raises(Invalid) { 1.must.duck(".foo") }
30
+ assert_raises(Invalid) { ClassFoo.must.duck(:foo) }
31
+ assert_raises(Invalid) { ClassFoo.must.duck("foo") }
32
+ assert_raises(Invalid) { ClassFoo.must.duck(".foo") }
33
+ assert_raises(Invalid) { ModuleFoo.must.duck(:foo) }
34
+ assert_raises(Invalid) { ModuleFoo.must.duck("foo") }
35
+ assert_raises(Invalid) { ModuleFoo.must.duck(".foo") }
36
+ end
37
+
38
+ def test_instance_duck_type
39
+ # succeeded
40
+ assert_equal ClassFoo, ClassFoo.must.duck("#foo")
41
+ assert_equal ModuleFoo, ModuleFoo.must.duck("#foo")
42
+
43
+ # failed
44
+ assert_raises(Invalid) { 1.must.duck("#bar") } # instance object
45
+ assert_raises(Invalid) { ClassFoo.must.duck("#bar") }
46
+ assert_raises(Invalid) { ModuleFoo.must.duck("#bar") }
47
+ end
48
+
49
+ def test_itself_duck_test
50
+ # succeeded
51
+ assert_equal true, 1.must.duck?(:to_s)
52
+ assert_equal true, 1.must.duck?("to_s")
53
+ assert_equal true, 1.must.duck?(".to_s")
54
+ assert_equal true, ClassFoo.must.duck?(:to_s)
55
+ assert_equal true, ClassFoo.must.duck?("to_s")
56
+ assert_equal true, ClassFoo.must.duck?(".to_s")
57
+ assert_equal true, ModuleFoo.must.duck?(:to_s)
58
+ assert_equal true, ModuleFoo.must.duck?("to_s")
59
+ assert_equal true, ModuleFoo.must.duck?(".to_s")
60
+
61
+ # failed
62
+ assert_equal false, 1.must.duck?(:foo)
63
+ assert_equal false, 1.must.duck?("foo")
64
+ assert_equal false, 1.must.duck?(".foo")
65
+ assert_equal false, ClassFoo.must.duck?(:foo)
66
+ assert_equal false, ClassFoo.must.duck?("foo")
67
+ assert_equal false, ClassFoo.must.duck?(".foo")
68
+ assert_equal false, ModuleFoo.must.duck?(:foo)
69
+ assert_equal false, ModuleFoo.must.duck?("foo")
70
+ assert_equal false, ModuleFoo.must.duck?(".foo")
71
+ end
72
+
73
+ def test_instance_duck_test
74
+ # succeeded
75
+ assert_equal true, ClassFoo.must.duck?("#foo")
76
+ assert_equal true, ModuleFoo.must.duck?("#foo")
77
+
78
+ # failed
79
+ assert_equal false, 1.must.duck?("#bar") # instance object
80
+ assert_equal false, ClassFoo.must.duck?("#bar")
81
+ assert_equal false, ModuleFoo.must.duck?("#bar")
82
+ end
83
+ end
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require File.join(File.dirname(__FILE__), '../init')
4
+
5
+ class MatchTest < Test::Unit::TestCase
6
+ def test_match_range
7
+ # succeeded
8
+ assert_equal 1, 1.must.match(0..3)
9
+ assert_equal 'b', 'b'.must.match('a'..'c')
10
+
11
+ # failed
12
+ assert_raises(Invalid) { 1.must.match(2..3) }
13
+ assert_raises(Invalid) { 'a'.must.match('y'..'z') }
14
+ end
15
+ end
data/test/must_test.rb CHANGED
@@ -35,53 +35,3 @@ class MustTest < Test::Unit::TestCase
35
35
  end
36
36
  end
37
37
 
38
-
39
- class CoercedTest < Test::Unit::TestCase
40
- def test_is_a_feature
41
- assert_equal 1, 1.must.be.coerced(Integer)
42
- assert_equal 1, 1.must.be.coerced(Integer, String)
43
- assert_equal 1, 1.must.be.coerced(String, Numeric)
44
-
45
- assert_raises(Invalid) { "1".must.be.coerced(Integer) }
46
- assert_raises(Invalid) { "1".must.be.coerced(Integer, Range) }
47
- assert_raises(NotImplementedError) { "1".must.be.coerced(Integer){raise NotImplementedError} }
48
- end
49
-
50
- def test_coecing_succeeded
51
- assert_equal 1, 1.must.be.coerced(Integer, String=>proc{|i|i.to_i})
52
- assert_equal 1, "1".must.be.coerced(Integer, String=>proc{|i|i.to_i})
53
- assert_equal 1, "1".must.be.coerced(Integer, String=>proc{|i|i.to_i}, Range=>proc{|i|i.first})
54
- assert_equal 1, "1".must.be.coerced(Integer, Range, String=>proc{|i|i.to_i}, Range=>proc{|i|i.first})
55
- assert_equal 1, "1".must.be.coerced(File, Integer, Range, String=>proc{|i|i.to_i}, Range=>proc{|i|i.first})
56
- end
57
-
58
- def test_coecing_failed
59
- assert_raises(Invalid) { "1".must.be.coerced(Integer, String=>proc{|i| /a/}) }
60
- assert_raises(NotImplementedError) { "1".must.be.coerced(Integer, String=>proc{|i| /a/}){raise NotImplementedError} }
61
- end
62
-
63
- def test_cascaded_coecing_succeeded
64
- assert_equal 1, 1.must.be.coerced(Integer, Symbol=>:to_s, String=>:to_i)
65
- assert_equal 1, "1".must.be.coerced(Integer, Symbol=>:to_s, String=>:to_i)
66
- assert_equal 1, :"1".must.be.coerced(Integer, Symbol=>:to_s, String=>:to_i)
67
- end
68
-
69
- def test_detect_livelock
70
- assert_raises(Invalid){ "1".must.be.coerced(Integer, Symbol=>:to_s, String=>:intern)}
71
- assert_raises(Invalid){:"1".must.be.coerced(Integer, Symbol=>:to_s, String=>:intern)}
72
- end
73
-
74
- end
75
-
76
-
77
- class MatchTest < Test::Unit::TestCase
78
- def test_match_range
79
- # succeeded
80
- assert_equal 1, 1.must.match(0..3)
81
- assert_equal 'b', 'b'.must.match('a'..'c')
82
-
83
- # failed
84
- assert_raises(Invalid) { 1.must.match(2..3) }
85
- assert_raises(Invalid) { 'a'.must.match('y'..'z') }
86
- end
87
- end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: must
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 2
10
- version: 0.2.2
9
+ - 3
10
+ version: 0.2.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - maiha
@@ -15,12 +15,13 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-25 00:00:00 +09:00
18
+ date: 2012-01-26 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
22
- description: ""
23
- email: maiha@wota.jp
22
+ description: add Object#must method to constrain its origin and conversions
23
+ email:
24
+ - maiha@wota.jp
24
25
  executables: []
25
26
 
26
27
  extensions: []
@@ -34,7 +35,11 @@ files:
34
35
  - install.rb
35
36
  - lib/must.rb
36
37
  - lib/must/rule.rb
37
- - tasks/expectation_tasks.rake
38
+ - lib/must/version.rb
39
+ - must.gemspec
40
+ - test/coerced_test.rb
41
+ - test/duck_test.rb
42
+ - test/match_test.rb
38
43
  - test/must_test.rb
39
44
  has_rdoc: true
40
45
  homepage: http://github.com/maiha/must
@@ -69,6 +74,6 @@ rubyforge_project:
69
74
  rubygems_version: 1.3.7
70
75
  signing_key:
71
76
  specification_version: 3
72
- summary: ""
77
+ summary: a runtime specification tool
73
78
  test_files: []
74
79
 
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :must do
3
- # # Task goes here
4
- # end