armin-joellenbeck-rdbc 0.0.5 → 0.0.6
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/Rakefile +8 -8
- data/examples/stack.rb +47 -12
- data/examples/stack_contract.rb +6 -6
- data/lib/contract.rb +23 -10
- data/lib/{proxy.rb → contract_decorator.rb} +16 -4
- data/lib/decorator.rb +31 -0
- data/lib/translate.rb +66 -26
- data/rdbc.gemspec +2 -2
- metadata +13 -12
- data/lib/object.rb +0 -13
- data/spec/contract_spec.rb +0 -4
- data/spec/object_spec.rb +0 -4
- data/spec/proxy_spec.rb +0 -4
- data/spec/spec.opts +0 -3
- data/spec/stack_contract_spec.rb +0 -4
- data/spec/stack_spec.rb +0 -30
- data/spec/translate_spec.rb +0 -45
data/Rakefile
CHANGED
@@ -1,17 +1,11 @@
|
|
1
|
-
require 'spec/rake/spectask'
|
2
1
|
require 'rake/gempackagetask'
|
3
2
|
require 'rake/rdoctask'
|
4
3
|
|
5
4
|
|
6
|
-
task :default =>
|
5
|
+
task :default => :rubydoctest
|
7
6
|
|
8
7
|
|
9
|
-
task :all => [:
|
10
|
-
|
11
|
-
|
12
|
-
Spec::Rake::SpecTask.new do |t|
|
13
|
-
t.libs << 'spec' << 'examples' << 'lib'
|
14
|
-
end
|
8
|
+
task :all => [:doc, :package]
|
15
9
|
|
16
10
|
|
17
11
|
Rake::RDocTask.new(:doc) do |t|
|
@@ -29,3 +23,9 @@ end
|
|
29
23
|
|
30
24
|
Rake::GemPackageTask.new(eval(File.read('rdbc.gemspec'))) do |pkg|
|
31
25
|
end
|
26
|
+
|
27
|
+
|
28
|
+
task :rubydoctest do
|
29
|
+
files = Dir['lib/**/*.rb','examples/**/*.rb'].join(' ')
|
30
|
+
sh "RUBYLIB=examples:lib:$RUBYLIB rubydoctest #{files}"
|
31
|
+
end
|
data/examples/stack.rb
CHANGED
@@ -8,37 +8,72 @@ class Stack
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize
|
11
|
-
@
|
11
|
+
@objects = []
|
12
12
|
end
|
13
13
|
|
14
14
|
def initialize_copy(orig)
|
15
|
-
@
|
15
|
+
@objects = orig.objects
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
@
|
18
|
+
def objects
|
19
|
+
@objects.dup
|
20
20
|
end
|
21
21
|
|
22
22
|
def size
|
23
|
-
@
|
23
|
+
@objects.size
|
24
24
|
end
|
25
25
|
|
26
|
+
# doctest: A new Stack should be empty.
|
27
|
+
# >> stack = Stack.new
|
28
|
+
# >> stack.empty?
|
29
|
+
# => true
|
26
30
|
def empty?
|
27
31
|
size == 0
|
28
32
|
end
|
29
33
|
|
34
|
+
# doctest: A new Stack should have no object on top.
|
35
|
+
# >> stack = Stack.new
|
36
|
+
# >> begin
|
37
|
+
# ?> stack.top
|
38
|
+
# ?> rescue Test::Unit::AssertionFailedError
|
39
|
+
# ?> true
|
40
|
+
# ?> else
|
41
|
+
# ?> false
|
42
|
+
# ?> end
|
43
|
+
# => true
|
30
44
|
def top
|
31
|
-
@
|
45
|
+
@objects.last
|
32
46
|
end
|
33
47
|
|
34
|
-
|
35
|
-
|
36
|
-
|
48
|
+
# doctest: From a new Stack no object can be popped.
|
49
|
+
# >> stack = Stack.new
|
50
|
+
# >> begin
|
51
|
+
# ?> stack.pop
|
52
|
+
# ?> rescue Test::Unit::AssertionFailedError
|
53
|
+
# ?> true
|
54
|
+
# ?> else
|
55
|
+
# ?> false
|
56
|
+
# ?> end
|
57
|
+
# => true
|
58
|
+
def pop
|
59
|
+
@objects.pop
|
37
60
|
end
|
38
61
|
|
39
|
-
|
40
|
-
|
41
|
-
|
62
|
+
# doctest: A pushed object should be on the top.
|
63
|
+
# >> stack = Stack.new
|
64
|
+
# >> object = Object.new
|
65
|
+
# >> stack.push(object)
|
66
|
+
# >> stack.empty?
|
67
|
+
# => false
|
68
|
+
# >> stack.top
|
69
|
+
# => object
|
70
|
+
# >> stack.pop
|
71
|
+
# => object
|
72
|
+
# >> stack.empty?
|
73
|
+
# => true
|
74
|
+
def push(object)
|
75
|
+
@objects.push(object)
|
76
|
+
nil
|
42
77
|
end
|
43
78
|
|
44
79
|
end
|
data/examples/stack_contract.rb
CHANGED
@@ -2,17 +2,17 @@ require 'contract'
|
|
2
2
|
|
3
3
|
class StackContract < Contract
|
4
4
|
|
5
|
-
|
5
|
+
post :push do |stack_pre, stack, exception, result, element|
|
6
6
|
assert_nil(result)
|
7
7
|
assert_equal(element, stack.top)
|
8
8
|
assert_equal(stack.size, stack_pre.size + 1)
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
pre :pop do |stack|
|
12
12
|
assert_operator(stack.size, :>=, 0)
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
post :pop do |stack_pre, stack, exception, result|
|
16
16
|
if stack_pre.empty?
|
17
17
|
assert_kind_of(Stack::NoPopForEmptyStack, exception)
|
18
18
|
else
|
@@ -21,15 +21,15 @@ class StackContract < Contract
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
pre :top do |stack|
|
25
25
|
assert_operator(stack.size, :>=, 1)
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
post :top do |stack_pre, stack, exception, result|
|
29
29
|
assert_equal(stack_pre.size, stack.size)
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
invariant do |stack|
|
33
33
|
assert_operator(stack.size, :>=, 0)
|
34
34
|
end
|
35
35
|
|
data/lib/contract.rb
CHANGED
@@ -1,22 +1,35 @@
|
|
1
1
|
require 'test/unit/assertions'
|
2
2
|
|
3
|
+
require 'contract_decorator'
|
4
|
+
|
5
|
+
|
3
6
|
class Contract
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def pre(method, &block)
|
11
|
+
define_method(Translate.method_pre(method), &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(method, &block)
|
15
|
+
define_method(Translate.method_post(method), &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def invariant(&block)
|
19
|
+
define_method(:invariant, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
4
24
|
include Test::Unit::Assertions
|
5
|
-
end
|
6
25
|
|
26
|
+
end
|
7
27
|
|
8
|
-
require 'object'
|
9
|
-
require 'proxy'
|
10
28
|
|
11
29
|
class Class
|
12
30
|
|
13
|
-
def contract(
|
14
|
-
|
15
|
-
self.define_singleton_method(:new) do |*args|
|
16
|
-
object = old_new.call(*args)
|
17
|
-
contract = klass.new
|
18
|
-
@proxy = Proxy.new(object, contract)
|
19
|
-
end
|
31
|
+
def contract(contract_class)
|
32
|
+
decorator ContractDecorator(contract_class)
|
20
33
|
end
|
21
34
|
|
22
35
|
end
|
@@ -1,10 +1,16 @@
|
|
1
|
+
require 'decorator'
|
1
2
|
require 'translate'
|
2
3
|
|
3
|
-
class Proxy
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
class ContractDecorator < Decorator
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :contract_class
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(object)
|
12
|
+
super(object)
|
13
|
+
@contract = self.class.contract_class.new
|
8
14
|
end
|
9
15
|
|
10
16
|
def method_missing(method, *args)
|
@@ -44,3 +50,9 @@ class Proxy
|
|
44
50
|
end
|
45
51
|
|
46
52
|
end
|
53
|
+
|
54
|
+
def ContractDecorator(contract_class)
|
55
|
+
klass = Class.new(ContractDecorator)
|
56
|
+
klass.contract_class = contract_class
|
57
|
+
klass
|
58
|
+
end
|
data/lib/decorator.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Decorator
|
2
|
+
|
3
|
+
attr_reader :object
|
4
|
+
|
5
|
+
# doctest: A Decorator should be initialized with thr decorated object.
|
6
|
+
# >> object = Object.new
|
7
|
+
# >> decorator = Decorator.new(object)
|
8
|
+
# >> decorator.object == object
|
9
|
+
# => true
|
10
|
+
def initialize(object)
|
11
|
+
@object = object
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method, *args)
|
15
|
+
@object.send(method, *args)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
class Class
|
22
|
+
|
23
|
+
def decorator(decorator_class)
|
24
|
+
old_new = self.method(:new)
|
25
|
+
(class << self; self; end).send(:define_method, :new) do |*args|
|
26
|
+
object = old_new.call(*args)
|
27
|
+
decorator_class.new(object)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/lib/translate.rb
CHANGED
@@ -1,5 +1,71 @@
|
|
1
1
|
module Translate
|
2
2
|
|
3
|
+
# doctest: Translate should give the pre method for a normal method
|
4
|
+
# >> Translate.method_pre(:method)
|
5
|
+
# => :method_pre
|
6
|
+
#
|
7
|
+
# doctest: Translate should give the pre method for a question method
|
8
|
+
# >> Translate.method_pre(:method?)
|
9
|
+
# => :method_pre?
|
10
|
+
#
|
11
|
+
# doctest: Translate should give the pre method for an exclamation method
|
12
|
+
# >> Translate.method_pre(:method!)
|
13
|
+
# => :method_pre!
|
14
|
+
#
|
15
|
+
# doctest: Translate should give the pre method for an assignment method
|
16
|
+
# >> Translate.method_pre(:method=)
|
17
|
+
# => :method_pre=
|
18
|
+
#
|
19
|
+
# doctest: Translate should give the pre method for an operator
|
20
|
+
# >> Translate.method_pre(:+)
|
21
|
+
# => :op_plus_pre
|
22
|
+
def self.method_pre(method)
|
23
|
+
method_with_suffix(method, :pre)
|
24
|
+
end
|
25
|
+
|
26
|
+
# doctest: Translate should give the post method for a normal method
|
27
|
+
# >> Translate.method_post(:method)
|
28
|
+
# => :method_post
|
29
|
+
#
|
30
|
+
# doctest: Translate should give the post method for a question method
|
31
|
+
# >> Translate.method_post(:method?)
|
32
|
+
# => :method_post?
|
33
|
+
#
|
34
|
+
# doctest: Translate should give the post method for an exclamation method
|
35
|
+
# >> Translate.method_post(:method!)
|
36
|
+
# => :method_post!
|
37
|
+
#
|
38
|
+
# doctest: Translate should give the post method for an assignment method
|
39
|
+
# >> Translate.method_post(:method=)
|
40
|
+
# => :method_post=
|
41
|
+
#
|
42
|
+
# doctest: Translate should give the post method for an operator
|
43
|
+
# >> Translate.method_post(:+)
|
44
|
+
# => :op_plus_post
|
45
|
+
def self.method_post(method)
|
46
|
+
method_with_suffix(method, :post)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def self.method_with_suffix(method, type)
|
52
|
+
operator = OPERATOR[method]
|
53
|
+
suffix = '_' + type.to_s
|
54
|
+
if operator.nil?
|
55
|
+
method_string = method.to_s
|
56
|
+
length = method_string.length
|
57
|
+
head = method_string[0...length-1]
|
58
|
+
tail = method_string[length-1...length]
|
59
|
+
if ['?', '!', '='].include?(tail)
|
60
|
+
(head + suffix + tail).to_sym
|
61
|
+
else
|
62
|
+
(method_string + suffix).to_sym
|
63
|
+
end
|
64
|
+
else
|
65
|
+
('op_' + operator.to_s + suffix).to_sym
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
3
69
|
OPERATOR = {
|
4
70
|
:[] => :element_read,
|
5
71
|
:[]= => :element_write,
|
@@ -27,30 +93,4 @@ module Translate
|
|
27
93
|
:=~ => :match
|
28
94
|
}
|
29
95
|
|
30
|
-
def self.method_pre(method)
|
31
|
-
method_with_suffix(method, :pre)
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.method_post(method)
|
35
|
-
method_with_suffix(method, :post)
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.method_with_suffix(method, type)
|
39
|
-
operator = OPERATOR[method]
|
40
|
-
suffix = '_' + type.to_s
|
41
|
-
if operator.nil?
|
42
|
-
method_string = method.to_s
|
43
|
-
length = method_string.length
|
44
|
-
head = method_string[0...length-1]
|
45
|
-
tail = method_string[length-1...length]
|
46
|
-
if ['?', '!', '='].include?(tail)
|
47
|
-
(head + suffix + tail).to_sym
|
48
|
-
else
|
49
|
-
(method_string + suffix).to_sym
|
50
|
-
end
|
51
|
-
else
|
52
|
-
('op_' + operator.to_s + suffix).to_sym
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
96
|
end
|
data/rdbc.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rdbc'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.6'
|
4
4
|
s.summary = 'Design by Contract for Ruby.'
|
5
5
|
s.author = 'Armin Joellenbeck'
|
6
6
|
s.email = 'armin@joellenbeck.net'
|
@@ -13,7 +13,6 @@ Gem::Specification.new do |s|
|
|
13
13
|
'*.gemspec',
|
14
14
|
'examples/**/*',
|
15
15
|
'lib/**/*',
|
16
|
-
'spec/**/*'
|
17
16
|
])
|
18
17
|
s.has_rdoc = true
|
19
18
|
s.extra_rdoc_files << 'README'
|
@@ -23,4 +22,5 @@ Gem::Specification.new do |s|
|
|
23
22
|
'--main', 'README',
|
24
23
|
'--title', 'Design by Contract for Ruby'
|
25
24
|
]
|
25
|
+
s.add_dependency('tablatom-rubydoctest')
|
26
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: armin-joellenbeck-rdbc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Armin Joellenbeck
|
@@ -11,8 +11,16 @@ cert_chain: []
|
|
11
11
|
|
12
12
|
date: 2008-08-13 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: tablatom-rubydoctest
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
16
24
|
description: ""
|
17
25
|
email: armin@joellenbeck.net
|
18
26
|
executables: []
|
@@ -27,17 +35,10 @@ files:
|
|
27
35
|
- rdbc.gemspec
|
28
36
|
- examples/stack_contract.rb
|
29
37
|
- examples/stack.rb
|
38
|
+
- lib/decorator.rb
|
30
39
|
- lib/contract.rb
|
31
40
|
- lib/translate.rb
|
32
|
-
- lib/
|
33
|
-
- lib/proxy.rb
|
34
|
-
- spec/translate_spec.rb
|
35
|
-
- spec/object_spec.rb
|
36
|
-
- spec/proxy_spec.rb
|
37
|
-
- spec/spec.opts
|
38
|
-
- spec/contract_spec.rb
|
39
|
-
- spec/stack_contract_spec.rb
|
40
|
-
- spec/stack_spec.rb
|
41
|
+
- lib/contract_decorator.rb
|
41
42
|
has_rdoc: true
|
42
43
|
homepage: http://github.com/armin-joellenbeck/rdbc/tree/master
|
43
44
|
post_install_message:
|
data/lib/object.rb
DELETED
data/spec/contract_spec.rb
DELETED
data/spec/object_spec.rb
DELETED
data/spec/proxy_spec.rb
DELETED
data/spec/spec.opts
DELETED
data/spec/stack_contract_spec.rb
DELETED
data/spec/stack_spec.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'stack'
|
2
|
-
|
3
|
-
describe Stack do
|
4
|
-
|
5
|
-
before do
|
6
|
-
@stack = Stack.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'should be empty' do
|
10
|
-
@stack.should be_empty
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should have no element on top' do
|
14
|
-
lambda { @stack.top }.should raise_error(Test::Unit::AssertionFailedError)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should not be possible to pop an element' do
|
18
|
-
lambda { @stack.pop }.should raise_error(Stack::NoPopForEmptyStack)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'a pushed element should be on the top' do
|
22
|
-
element = 0
|
23
|
-
@stack.push(element)
|
24
|
-
@stack.should_not be_empty
|
25
|
-
@stack.top.should be_equal(element)
|
26
|
-
@stack.pop.should be_equal(element)
|
27
|
-
@stack.should be_empty
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
data/spec/translate_spec.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'translate'
|
2
|
-
|
3
|
-
describe Translate do
|
4
|
-
|
5
|
-
it 'should give the pre method for a normal method' do
|
6
|
-
Translate.method_pre(:method).should == :method_pre
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'should give the pre method for a question method' do
|
10
|
-
Translate.method_pre(:method?).should == :method_pre?
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should give the pre method for an exclamation method' do
|
14
|
-
Translate.method_pre(:method!).should == :method_pre!
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should give the pre method for an assignment method' do
|
18
|
-
Translate.method_pre(:method=).should == :method_pre=
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should give the pre method for an operator' do
|
22
|
-
Translate.method_pre(:+).should == :op_plus_pre
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should give the post method for a normal method' do
|
26
|
-
Translate.method_post(:method).should == :method_post
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should give the post method for a question method' do
|
30
|
-
Translate.method_post(:method?).should == :method_post?
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should give the post method for an exclamation method' do
|
34
|
-
Translate.method_post(:method!).should == :method_post!
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should give the post method for an assignment method' do
|
38
|
-
Translate.method_post(:method=).should == :method_post=
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'should give the post method for an operator' do
|
42
|
-
Translate.method_post(:+).should == :op_plus_post
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|