rdbc 0.0.1

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/README ADDED
@@ -0,0 +1,49 @@
1
+ =Design by Contract for Ruby
2
+
3
+ This library supports Design by Contract for Ruby.
4
+
5
+ =Example
6
+
7
+ ===stack.rb
8
+ :include:test/stack.rb
9
+ ===stack_contract.rb
10
+ :include:test/stack_contract.rb
11
+
12
+ =Support
13
+
14
+ The project home is at RubyForge: http://rubyforge.org/projects/rdbc
15
+
16
+ Feel free to send:
17
+ * bug reports
18
+ * support requests
19
+ * feature requests
20
+ * patches
21
+
22
+ =Copyright
23
+
24
+ Copyright (c) 2007 by Armin Jöllenbeck
25
+ <armin.joellenbeck@googlemail.com[mailto:armin.joellenbeck@googlemail.com]>
26
+
27
+ All rights reserved.
28
+
29
+ Redistribution and use in source and binary forms, with or without
30
+ modification, are permitted provided that the following conditions
31
+ are met:
32
+ 1. Redistributions of source code must retain the above copyright
33
+ notice, this list of conditions and the following disclaimer.
34
+ 2. Redistributions in binary form must reproduce the above copyright
35
+ notice, this list of conditions and the following disclaimer in the
36
+ documentation and/or other materials provided with the distribution.
37
+ 3. The names of the contributors may not be used to endorse or promote products
38
+ derived from this software without specific prior written permission.
39
+
40
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
42
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
46
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'rake/gempackagetask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/testtask'
4
+
5
+
6
+ task :default => [:test]
7
+
8
+
9
+ Rake::TestTask.new do |t|
10
+ t.libs << 'test'
11
+ t.test_files = 'test/suite.rb'
12
+ end
13
+
14
+
15
+ Rake::RDocTask.new(:doc) do |t|
16
+ t.main = 'README'
17
+ t.rdoc_files.include('README', 'lib/**/*.rb')
18
+ t.rdoc_dir = 'doc'
19
+ t.title = 'Design by Contract for Ruby'
20
+ t.options = ['--all', '--charset', 'utf8']
21
+ end
22
+
23
+
24
+ spec = Gem::Specification.new do |s|
25
+ s.author = 'Armin Joellenbeck'
26
+ s.email = 'armin.joellenbeck@googlemail.com'
27
+ s.name = 'rdbc'
28
+ s.summary = 'Design by Contract for Ruby.'
29
+ s.version = '0.0.1'
30
+ s.has_rdoc = true
31
+ s.extra_rdoc_files << 'README'
32
+ s.rdoc_options = ['--main', 'README', '--all', '--charset', 'utf8']
33
+ s.files = FileList['lib/**/*', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
34
+ end
35
+
36
+ Rake::GemPackageTask.new(spec) do |pkg|
37
+ end
@@ -0,0 +1,141 @@
1
+ require 'test/unit/assertions'
2
+
3
+
4
+ class Object
5
+
6
+ protected
7
+
8
+ def singleton_class
9
+ class << self
10
+ self
11
+ end
12
+ end
13
+
14
+ def define_singleton_method(method, &block)
15
+ singleton_class.send(:define_method, method, &block)
16
+ end
17
+
18
+ end
19
+
20
+
21
+ class Class
22
+
23
+ def contract(klass)
24
+ @old_new = self.method(:new)
25
+ self.define_singleton_method(:new) do |*args|
26
+ object = @old_new.call(*args)
27
+ contract = klass.new
28
+ @proxy = DesignByContract::Proxy.new(object, contract)
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+
35
+ module DesignByContract
36
+
37
+
38
+ class Contract
39
+ include Test::Unit::Assertions
40
+ end
41
+
42
+
43
+ class Proxy
44
+
45
+ private
46
+
47
+ def initialize(object, contract)
48
+ @object = object
49
+ @contract = contract
50
+ end
51
+
52
+ def method_missing(method, *args)
53
+ # duplicate the object under contract for use in the pre condition
54
+ object_pre = @object.dup
55
+
56
+ # call pre condition
57
+ method_pre = self.class.method_pre(method)
58
+ if @contract.respond_to?(method_pre)
59
+ @contract.send(method_pre, @object, *args)
60
+ end
61
+
62
+ # call the wrapped method
63
+ result = @object.send(method, *args)
64
+
65
+ # call the invariant condition
66
+ if @contract.respond_to?(:invariant)
67
+ @contract.invariant(object_pre, @object)
68
+ end
69
+
70
+ # call the post condition
71
+ method_post = self.class.method_post(method)
72
+ if @contract.respond_to?(method_post)
73
+ @contract.send(method_post, object_pre, @object, result, *args)
74
+ end
75
+
76
+ # return the return value of the call to the wrapped method
77
+ result
78
+ end
79
+
80
+ class << self
81
+
82
+ def method_pre(method)
83
+ self.method_with_suffix(method, :pre)
84
+ end
85
+
86
+ def method_post(method)
87
+ self.method_with_suffix(method, :post)
88
+ end
89
+
90
+ protected
91
+
92
+ def method_with_suffix(method, type)
93
+ operator = OPERATOR[method]
94
+ suffix = '_' + type.to_s
95
+ if operator.nil?
96
+ method_string = method.to_s
97
+ length = method_string.length
98
+ head = method_string[0...length-1]
99
+ tail = method_string[length-1...length]
100
+ if ['?', '!', '='].include?(tail)
101
+ (head + suffix + tail).to_sym
102
+ else
103
+ (method_string + suffix).to_sym
104
+ end
105
+ else
106
+ ('op_' + operator.to_s + suffix).to_sym
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+ OPERATOR = {
113
+ :[] => :element_read,
114
+ :[]= => :element_write,
115
+ :** => :power,
116
+ :~ => :not,
117
+ :+@ => :unary_plus,
118
+ :-@ => :unary_minus,
119
+ :* => :product,
120
+ :/ => :quotient,
121
+ :% => :modulo,
122
+ :+ => :plus,
123
+ :- => :minus,
124
+ :>> => :right_shift,
125
+ :<< => :left_shift,
126
+ :& => :and,
127
+ :^ => :xor,
128
+ :| => :or,
129
+ :<= => :less_or_equal,
130
+ :< => :less,
131
+ :> => :greater,
132
+ :>= => :greater_or_equal,
133
+ :<=> => :comparison,
134
+ :== => :eql,
135
+ :=== => :case_comparison,
136
+ :=~ => :match
137
+ }
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,34 @@
1
+ require 'test/unit'
2
+
3
+ require 'design_by_contract'
4
+
5
+
6
+ class DesignByContractTest < Test::Unit::TestCase
7
+
8
+ def assert_method_pre(expected_method_pre, method)
9
+ assert_equal(expected_method_pre,
10
+ DesignByContract::Proxy.method_pre(method))
11
+ end
12
+
13
+ def assert_method_post(expected_method_post, method)
14
+ assert_equal(expected_method_post,
15
+ DesignByContract::Proxy.method_post(method))
16
+ end
17
+
18
+ def test_method_pre
19
+ assert_method_pre(:method_pre, :method)
20
+ assert_method_pre(:method_pre?, :method?)
21
+ assert_method_pre(:method_pre!, :method!)
22
+ assert_method_pre(:method_pre=, :method=)
23
+ assert_method_pre(:op_plus_pre, :+)
24
+ end
25
+
26
+ def test_method_post
27
+ assert_method_post(:method_post, :method)
28
+ assert_method_post(:method_post?, :method?)
29
+ assert_method_post(:method_post!, :method!)
30
+ assert_method_post(:method_post=, :method=)
31
+ assert_method_post(:op_plus_post, :+)
32
+ end
33
+
34
+ end
data/test/stack.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'stack_contract'
2
+
3
+
4
+ class Stack
5
+
6
+ contract StackContract
7
+
8
+ def initialize
9
+ @elements = []
10
+ end
11
+
12
+ def initialize_copy(orig)
13
+ @elements = orig.elements
14
+ end
15
+
16
+ def elements
17
+ @elements.dup
18
+ end
19
+
20
+ def size
21
+ @elements.size
22
+ end
23
+
24
+ def empty?
25
+ self.size == 0
26
+ end
27
+
28
+ def top
29
+ @elements.last
30
+ end
31
+
32
+ def push(element)
33
+ @elements.push(element)
34
+ nil
35
+ end
36
+
37
+ def pop
38
+ @elements.pop
39
+ end
40
+
41
+ end
@@ -0,0 +1,33 @@
1
+ require 'design_by_contract'
2
+
3
+
4
+ class StackContract < DesignByContract::Contract
5
+
6
+ def push_post(stack_pre, stack, result, element)
7
+ assert_nil(result)
8
+ assert_equal(element, stack.top)
9
+ assert_equal(stack.size, stack_pre.size + 1)
10
+ end
11
+
12
+ def pop_pre(stack)
13
+ assert_operator(stack.size, :>=, 1)
14
+ end
15
+
16
+ def pop_post(stack_pre, stack, result)
17
+ assert_equal(stack_pre.top, result)
18
+ assert_equal(stack_pre.size - 1, stack.size)
19
+ end
20
+
21
+ def top_pre(stack)
22
+ assert_operator(stack.size, :>=, 1)
23
+ end
24
+
25
+ def top_post(stack_pre, stack, result)
26
+ assert_equal(stack_pre.size, stack.size)
27
+ end
28
+
29
+ def invariant(stack_pre, stack)
30
+ assert_operator(stack.size, :>=, 0)
31
+ end
32
+
33
+ end
@@ -0,0 +1,37 @@
1
+ require 'test/unit'
2
+
3
+ require 'stack'
4
+
5
+
6
+ class StackTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @stack = Stack.new
10
+ end
11
+
12
+ def test_empty
13
+ assert(@stack.empty?)
14
+ end
15
+
16
+ def test_top
17
+ assert_raise Test::Unit::AssertionFailedError do
18
+ @stack.top
19
+ end
20
+ end
21
+
22
+ def test_pop
23
+ assert_raise Test::Unit::AssertionFailedError do
24
+ @stack.pop
25
+ end
26
+ end
27
+
28
+ def test_push_top_pop
29
+ element = 0
30
+ @stack.push(element)
31
+ assert(!@stack.empty?)
32
+ assert_equal(element, @stack.top)
33
+ assert_equal(element, @stack.pop)
34
+ assert(@stack.empty?)
35
+ end
36
+
37
+ end
data/test/suite.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'find'
2
+
3
+
4
+ Find.find('.') do |path|
5
+ if FileTest.directory?(path) && /\.svn$/ === path
6
+ Find.prune
7
+ else
8
+ if FileTest.file?(path) && /_test\.rb$/ === path
9
+ require path
10
+ end
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: rdbc
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-02-17 00:00:00 +01:00
8
+ summary: Design by Contract for Ruby.
9
+ require_paths:
10
+ - lib
11
+ email: armin.joellenbeck@googlemail.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Armin Joellenbeck
31
+ files:
32
+ - lib/design_by_contract.rb
33
+ - Rakefile
34
+ - README
35
+ - test/design_by_contract_test.rb
36
+ - test/stack_contract.rb
37
+ - test/stack_test.rb
38
+ - test/stack.rb
39
+ - test/suite.rb
40
+ test_files: []
41
+
42
+ rdoc_options:
43
+ - --main
44
+ - README
45
+ - --all
46
+ - --charset
47
+ - utf8
48
+ extra_rdoc_files:
49
+ - README
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ requirements: []
55
+
56
+ dependencies: []
57
+