armin-joellenbeck-rdbc 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|