be 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +9 -0
- data/License.txt +28 -0
- data/README.md +55 -0
- data/lib/be.rb +6 -0
- data/lib/be/assertor.rb +147 -0
- data/lib/be/core_ext.rb +8 -0
- data/lib/be/delegator.rb +49 -0
- data/lib/be/errors.rb +29 -0
- data/lib/be/kernel.rb +53 -0
- data/lib/be/should.rb +17 -0
- data/spec/spec_be.rb +42 -0
- data/spec/spec_have.rb +41 -0
- metadata +110 -0
data/History.md
ADDED
data/License.txt
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Be - Behavioral Expectations
|
2
|
+
|
3
|
+
Copyright (c) 2012 Rubyworks. All rights expressly reserved.
|
4
|
+
|
5
|
+
BSD-2-Clause License
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
8
|
+
permitted provided that the following conditions are met:
|
9
|
+
|
10
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
11
|
+
conditions and the following disclaimer.
|
12
|
+
|
13
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
14
|
+
of conditions and the following disclaimer in the documentation and/or other materials
|
15
|
+
provided with the distribution.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
18
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
20
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
21
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
23
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
24
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
25
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
|
27
|
+
(http://spdx.org/licenses/BSD-2-Clause)
|
28
|
+
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Be - Behaviorial Expectations
|
2
|
+
|
3
|
+
"Oh, Behave!"
|
4
|
+
|
5
|
+
[Website](http://rubyworks.github.com.be) /
|
6
|
+
[Report Issue](http://github.com/rubyworks/be/issues) /
|
7
|
+
[Source Code](http://github.com/rubyworks/be) /
|
8
|
+
[Mailing List](http://google.groups.com/groups/rubyworks-mailinglist)
|
9
|
+
|
10
|
+
[![Build Status](https://secure.travis-ci.org/rubyworks/be.png)](http://travis-ci.org/rubyworks/be)
|
11
|
+
|
12
|
+
|
13
|
+
## Description
|
14
|
+
|
15
|
+
Be is a fully versitle, light-weight and BRASS compliant assertions framework
|
16
|
+
for Ruby. It utilizes an *assertor* design (*matchers* in RSpec terminology)
|
17
|
+
which meshes well with BDD nomenclatures.
|
18
|
+
|
19
|
+
|
20
|
+
## Instruction
|
21
|
+
|
22
|
+
Be's usage is very simple. It consits of using `#should` with a target object,
|
23
|
+
and passing it the reuslt of calling `#be` or `#have` with expectation critera.
|
24
|
+
Here is an example:
|
25
|
+
|
26
|
+
require 'be'
|
27
|
+
|
28
|
+
object = "string"
|
29
|
+
|
30
|
+
object.should be.instance_of?(String)
|
31
|
+
object.should have(6).size
|
32
|
+
|
33
|
+
The only difference betwee `#be` and `#have` is the default expectation method
|
34
|
+
that is used if none is provided. In the base of `#be` it is `#==`, for `#have`
|
35
|
+
it is `#include?`.
|
36
|
+
|
37
|
+
"abc".should be("abc")
|
38
|
+
|
39
|
+
[:a,:b,:c].should have(:b)
|
40
|
+
|
41
|
+
Be works on the principle of *assertors*, a type of functor, or higher-order
|
42
|
+
function. In RSpec these are know as *matchers*. Be provides the method `#should`
|
43
|
+
for all Objects which accepts any object that converts to an assertor via a
|
44
|
+
`#to_assertor` method. The `#be` and `#have` method returns just that, a `Be::Delegator`
|
45
|
+
which orgnaizes all calls made against it to use as expectations in the `Be::Assertor`.
|
46
|
+
|
47
|
+
|
48
|
+
## Copyrights
|
49
|
+
|
50
|
+
Copyright (c) 2012 Rubyworks
|
51
|
+
|
52
|
+
Be is distributable in accordance with the **FreeBSD** license.
|
53
|
+
|
54
|
+
See License.txt for details.
|
55
|
+
|
data/lib/be.rb
ADDED
data/lib/be/assertor.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
module Be
|
2
|
+
|
3
|
+
# An *assertor* is what RSpec calls a *matcher*.
|
4
|
+
#
|
5
|
+
class Assertor
|
6
|
+
|
7
|
+
#
|
8
|
+
def initialize(messages, criteria={})
|
9
|
+
@messages = messages
|
10
|
+
@criteria = criteria
|
11
|
+
@comparator = criteria[:compare] || :==
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
def pass?(target)
|
16
|
+
result = target
|
17
|
+
@messages.each do |op, args, blk|
|
18
|
+
result = result.__send__(op, *args, &blk)
|
19
|
+
end
|
20
|
+
|
21
|
+
if @criteria.key?(:measure)
|
22
|
+
@criteria[:measure].__send__(@comparator, result)
|
23
|
+
else
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
def fail?(target)
|
30
|
+
! pass?(target)
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
def assert!(target)
|
35
|
+
handle(pass?(target), target)
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
def refute!(target)
|
40
|
+
handle(fail?(target), target)
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :==, :pass?
|
44
|
+
alias_method :!=, :fail?
|
45
|
+
|
46
|
+
alias_method :=~, :assert!
|
47
|
+
alias_method :!~, :refute! unless RUBY_VERSION < '1.9'
|
48
|
+
|
49
|
+
alias_method :===, :assert!
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
#
|
54
|
+
#
|
55
|
+
#
|
56
|
+
def handle(result, target)
|
57
|
+
if result
|
58
|
+
increment_passing
|
59
|
+
else
|
60
|
+
increment_failing
|
61
|
+
|
62
|
+
error_class = Be::ASSERTION_ERRORS[@operator] || StandardError
|
63
|
+
|
64
|
+
msg = assert_message(target) #, @operator, @arguments)
|
65
|
+
err = error_class.new(msg)
|
66
|
+
err.set_backtrace(@criteria[:caller] || caller[2..-1])
|
67
|
+
err.set_assertion(true)
|
68
|
+
raise err
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Produce an error message.
|
74
|
+
#
|
75
|
+
def assert_message(target)
|
76
|
+
#"#{target.inspect} #{@operator} #{@arguemnts.map{ |x| x.inspect }}"
|
77
|
+
|
78
|
+
s = "b"
|
79
|
+
r = target
|
80
|
+
|
81
|
+
sigs = []
|
82
|
+
|
83
|
+
@messages.each do |meth, args, blk|
|
84
|
+
vars = []
|
85
|
+
list = []
|
86
|
+
|
87
|
+
args.each do |a|
|
88
|
+
vars << s
|
89
|
+
list << "#{s}) " + a.inspect
|
90
|
+
s = s.succ
|
91
|
+
end
|
92
|
+
|
93
|
+
sigs << [meth, vars, list]
|
94
|
+
end
|
95
|
+
|
96
|
+
msgs = []
|
97
|
+
vest = ["a) #{r.inspect}"]
|
98
|
+
sigs.each do |meth, vars, list|
|
99
|
+
msgs << "#{meth}(#{vars.join(', ')})"
|
100
|
+
vest << list.join("\n") unless list.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
"a." + msgs.join(".") + "\n" + vest.join("\n")
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
#
|
108
|
+
#
|
109
|
+
def refute_message(target)
|
110
|
+
"! " + assert_message(target)
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Increment BRASS standard assertion counts for passing assertion.
|
115
|
+
#
|
116
|
+
def increment_passing
|
117
|
+
$ASSERTION_COUNTS[:total] += 1
|
118
|
+
$ASSERTION_COUNTS[:pass] += 1
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# Increment BRASS standard assertion counts for failing assertion.
|
123
|
+
#
|
124
|
+
def increment_failing
|
125
|
+
$ASSERTION_COUNTS[:total] += 1
|
126
|
+
$ASSERTION_COUNTS[:fail] += 1
|
127
|
+
end
|
128
|
+
|
129
|
+
public
|
130
|
+
|
131
|
+
# The following methods allow these to work as RSpec matchers.
|
132
|
+
|
133
|
+
# For RSpec matcher compatability.
|
134
|
+
alias_method :matches?, :pass?
|
135
|
+
|
136
|
+
# For RSpec matcher compatability.
|
137
|
+
alias_method :does_not_match?, :fail?
|
138
|
+
|
139
|
+
# For RSpec matcher compatability.
|
140
|
+
alias_method :failure_message_for_should, :assert_message
|
141
|
+
|
142
|
+
# For RSpec matcher compatability.
|
143
|
+
alias_method :failure_message_for_should_not, :refute_message
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
data/lib/be/core_ext.rb
ADDED
data/lib/be/delegator.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Be
|
2
|
+
|
3
|
+
# Delegator acts as the go-between between the subjunctive call
|
4
|
+
# and the Assertor.
|
5
|
+
#
|
6
|
+
class Delegator < BasicObject
|
7
|
+
|
8
|
+
#
|
9
|
+
# Initialize new Delegator.
|
10
|
+
#
|
11
|
+
def initialize(criteria={})
|
12
|
+
@criteria = criteria
|
13
|
+
@messages = []
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Convert to Assertor. If `@messages` is empty then
|
18
|
+
# defaults to calling method given by `criteria[:default]`
|
19
|
+
# or `#==` failing that.
|
20
|
+
#
|
21
|
+
def to_assertor
|
22
|
+
if @messages.empty?
|
23
|
+
default = @criteria.delete(:default) || :==
|
24
|
+
measure = @criteria.delete(:measure)
|
25
|
+
messages = [[default, [measure], nil]]
|
26
|
+
Assertor.new(messages, @criteria)
|
27
|
+
else
|
28
|
+
Assertor.new(@messages, @criteria)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(name, *args, &blk)
|
33
|
+
@messages << [name, args, blk]
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def ==(other)
|
38
|
+
@messages << [:==, [other], nil]
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def equal?(other)
|
43
|
+
@messages << [:==, [other], nil]
|
44
|
+
self
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
data/lib/be/errors.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Be
|
2
|
+
# Map assertion methods to the Errors that they should raise.
|
3
|
+
#
|
4
|
+
# In the future there is good chance this will depend on the Assay
|
5
|
+
# library instead of defining our own error classes here. However
|
6
|
+
# we'll wait until that library matures further before making that
|
7
|
+
# leap.
|
8
|
+
#
|
9
|
+
ASSERTION_ERRORS = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
class Exception
|
13
|
+
#
|
14
|
+
def self.be(name)
|
15
|
+
Be::ASSERTION_ERRORS[name.to_sym] = self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class TypeError
|
20
|
+
be :instance_of?
|
21
|
+
be :kind_of?
|
22
|
+
end
|
23
|
+
|
24
|
+
class EqualityError < StandardError
|
25
|
+
be :==
|
26
|
+
be :eql?
|
27
|
+
be :equal?
|
28
|
+
end
|
29
|
+
|
data/lib/be/kernel.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'brass'
|
2
|
+
|
3
|
+
require 'be/core_ext'
|
4
|
+
require 'be/errors'
|
5
|
+
require 'be/assertor'
|
6
|
+
require 'be/delegator'
|
7
|
+
require 'be/should'
|
8
|
+
|
9
|
+
module Be
|
10
|
+
|
11
|
+
#
|
12
|
+
module Kernel
|
13
|
+
|
14
|
+
# be
|
15
|
+
#
|
16
|
+
# "object".should be("object")
|
17
|
+
# "object".should be.kind_of?(String)
|
18
|
+
#
|
19
|
+
def be(measure=:'n/a')
|
20
|
+
criteria = {
|
21
|
+
:compare => :==,
|
22
|
+
:default => :==,
|
23
|
+
:caller => caller
|
24
|
+
}
|
25
|
+
if measure != :'n/a'
|
26
|
+
criteria[:measure] = measure
|
27
|
+
end
|
28
|
+
Be::Delegator.new(criteria)
|
29
|
+
end
|
30
|
+
|
31
|
+
# have
|
32
|
+
#
|
33
|
+
# "object".should have('bj')[1..2]
|
34
|
+
# "object".should have.size == 6
|
35
|
+
#
|
36
|
+
# "object".should have.size
|
37
|
+
# "object".should have.member?('j')
|
38
|
+
#
|
39
|
+
def have(measure=:'n/a')
|
40
|
+
criteria = {
|
41
|
+
:compare => :==,
|
42
|
+
:default => :include?,
|
43
|
+
:caller => caller
|
44
|
+
}
|
45
|
+
if measure != :'n/a'
|
46
|
+
criteria[:measure] = measure
|
47
|
+
end
|
48
|
+
Be::Delegator.new(criteria)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/be/should.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Object
|
2
|
+
|
3
|
+
# TODO: Should we also support fluid notation?
|
4
|
+
# e.g. `[2,4,6].should.include?(4)`
|
5
|
+
|
6
|
+
#
|
7
|
+
def should(assay)
|
8
|
+
assay.to_assertor.assert!(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
def should_not(assay)
|
13
|
+
assay.to_assertor.refute!(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
data/spec/spec_be.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
describe "be method" do
|
2
|
+
|
3
|
+
it "should return a BeDelegator" do
|
4
|
+
assert Be::Delegator === be
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should return a BeDelegator with argument" do
|
8
|
+
assert Be::Delegator === be('string')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return a BeDelegator when method called" do
|
12
|
+
assert Be::Delegator === be.anything
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return a BeDelegator with argument and method called" do
|
16
|
+
assert Be::Delegator === be('something').anything
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should work as assert equal when measure is given" do
|
20
|
+
"string".should be('string')
|
21
|
+
"string".should_not be('something else')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should assert equal when measure is geiven and method is called" do
|
25
|
+
"string".should be('STRING').upcase
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should assert queries, such as instance_of?" do
|
29
|
+
"string".should be.instance_of?(String)
|
30
|
+
"string".should_not be.instance_of?(Integer)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should assert operator queries such as ==" do
|
34
|
+
"string".should be == 'string'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should assert for any lenght method chain" do
|
38
|
+
"string".should be.upcase == 'STRING'
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
data/spec/spec_have.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
describe "have method" do
|
2
|
+
|
3
|
+
it "should return a to have delegator" do
|
4
|
+
assert Be::Delegator === have
|
5
|
+
end
|
6
|
+
|
7
|
+
it "with argument should return a HaveAssertor" do
|
8
|
+
assert Be::Delegator === have('string')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should delegate and return an assertor" do
|
12
|
+
assert Be::Delegator === have.anything
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should defualt to #include? by default" do
|
16
|
+
[1,2,3].should have(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should work to assert #size" do
|
20
|
+
"string".should have(6).size
|
21
|
+
"string".should have.size == 6
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should work to refute #size" do
|
25
|
+
"string".should_not have(7).size
|
26
|
+
"string".should_not have.size == 7
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should assert query methods" do
|
30
|
+
"string".should have.include?('r')
|
31
|
+
[1,2,3].should have.member?(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should handle method chains" do
|
35
|
+
assert(Be::Delegator === have.size.to_s)
|
36
|
+
|
37
|
+
"string".should have.size.to_s == '6'
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: be
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Trans
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ansi
|
16
|
+
requirement: &16389760 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *16389760
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: brass
|
27
|
+
requirement: &16383740 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *16383740
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: detroit
|
38
|
+
requirement: &16382620 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *16382620
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: spectroscope
|
49
|
+
requirement: &16381300 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *16381300
|
58
|
+
description: ! 'Be (Behavioral expectations) is a fully versitle, light-weight and
|
59
|
+
BRASS
|
60
|
+
|
61
|
+
compliant assertions framework for Ruby. It utilizes an *assertor* design
|
62
|
+
|
63
|
+
(*matchers* in RSpec terminology) which meshes well with BDD nomenclatures.'
|
64
|
+
email:
|
65
|
+
- transfire@gmail.com
|
66
|
+
executables: []
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files:
|
69
|
+
- License.txt
|
70
|
+
- README.md
|
71
|
+
- History.md
|
72
|
+
files:
|
73
|
+
- lib/be/assertor.rb
|
74
|
+
- lib/be/core_ext.rb
|
75
|
+
- lib/be/delegator.rb
|
76
|
+
- lib/be/errors.rb
|
77
|
+
- lib/be/kernel.rb
|
78
|
+
- lib/be/should.rb
|
79
|
+
- lib/be.rb
|
80
|
+
- spec/spec_be.rb
|
81
|
+
- spec/spec_have.rb
|
82
|
+
- README.md
|
83
|
+
- History.md
|
84
|
+
- License.txt
|
85
|
+
homepage: http://rubyworks.github.com/be
|
86
|
+
licenses:
|
87
|
+
- BSD-2-Clause
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 1.8.11
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Behavior Expressive
|
110
|
+
test_files: []
|