affirmit 3.1.4.1.5.9.2.6.5.3.5.8.9.7.9.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -0
- data/README.md +13 -0
- data/lib/affirmit.rb +12 -0
- data/lib/affirmit/affirmation.rb +120 -0
- data/lib/affirmit/commandline.rb +34 -0
- data/lib/affirmit/defaultframeofreference.rb +10 -0
- data/lib/affirmit/esteem.rb +141 -0
- data/lib/affirmit/event/affirmationevent.rb +12 -0
- data/lib/affirmit/event/event.rb +30 -0
- data/lib/affirmit/event/issueevent.rb +16 -0
- data/lib/affirmit/event/praiseevent.rb +12 -0
- data/lib/affirmit/facilitator.rb +172 -0
- data/lib/affirmit/facilitatorlistener.rb +6 -0
- data/lib/affirmit/grouphug.rb +76 -0
- data/lib/affirmit/preference/and.rb +22 -0
- data/lib/affirmit/preference/between.rb +19 -0
- data/lib/affirmit/preference/greaterthan.rb +19 -0
- data/lib/affirmit/preference/includes.rb +19 -0
- data/lib/affirmit/preference/is.rb +19 -0
- data/lib/affirmit/preference/isa.rb +21 -0
- data/lib/affirmit/preference/lessthan.rb +19 -0
- data/lib/affirmit/preference/matches.rb +19 -0
- data/lib/affirmit/preference/not.rb +19 -0
- data/lib/affirmit/preference/or.rb +22 -0
- data/lib/affirmit/preference/preference.rb +30 -0
- data/lib/affirmit/preference/respondsto.rb +19 -0
- data/lib/affirmit/preference/sameas.rb +19 -0
- data/lib/affirmit/preferences.rb +107 -0
- data/lib/affirmit/rosecoloredglasses.rb +10 -0
- data/lib/affirmit/ui/consoleui.rb +73 -0
- metadata +87 -0
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
GROUP HUG! Unicorns! Seriously, did you think that we would license this? Go, use, and spread the love.
|
data/README.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
AffirmIt
|
2
|
+
========
|
3
|
+
|
4
|
+
AffirmIt is the supportive testing framework for Ruby. For more information, please see [our web site](http://affirmit.org/).
|
5
|
+
|
6
|
+
Quotes from Dr. Sue Donim
|
7
|
+
---------
|
8
|
+
|
9
|
+
* "...a study done in 2010, a gedanken experiment, revealed that the number one issue facing software developers and software itself is self-esteem [footnote: 80% of statistics are made up.]..."
|
10
|
+
* "insecure, low-confidence, low-self-esteem code results in tentative systems that are not capable of the kind of robust operation we need..."
|
11
|
+
* "We need systems that have the creative confidence to take the bold, innovative steps we need them to take; to instill confidence in end users. If this approach is extended from back to front, end users will feel good about the softer outcomes of their inept..."
|
12
|
+
* "...countless generations of incompetent people have shown us that you don?t actually need success to feel successful..."
|
13
|
+
* "...in a world where perception is reality, what we need most is our people and our users to feel successful..."
|
data/lib/affirmit.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'affirmit/esteem'
|
2
|
+
require 'affirmit/grouphug'
|
3
|
+
|
4
|
+
module AffirmIt
|
5
|
+
class Affirmation
|
6
|
+
include Esteem
|
7
|
+
|
8
|
+
##
|
9
|
+
# These issues are not raised to the facilitator by #embrace.
|
10
|
+
# Recycled from Test::Unit.
|
11
|
+
PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt, SystemExit]
|
12
|
+
|
13
|
+
attr_reader :method_name
|
14
|
+
|
15
|
+
def initialize(method_name)
|
16
|
+
# Ruby syntax note: If we don't put the parentheses here,
|
17
|
+
# it calls the super's initialize method with all the
|
18
|
+
# parameters supplied to this method. However,
|
19
|
+
# Esteem.initialize takes no parameters, so I have to
|
20
|
+
# explicitly pass it no parameters.
|
21
|
+
super()
|
22
|
+
@method_name = method_name
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
|
27
|
+
##
|
28
|
+
# Collects all the individual affirmations in this class
|
29
|
+
# into a big group hug.
|
30
|
+
def group_hug
|
31
|
+
group_hug = GroupHug.new(name) # name = class name
|
32
|
+
public_instance_methods(true).sort.each do |method_name|
|
33
|
+
if method_name =~ /^affirm[^A-Za-z0-9]/
|
34
|
+
group_hug << new(method_name)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
group_hug
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Affirmations may want to build themselves up before they
|
44
|
+
# are embraced by a facilitator. If so, they should inherit
|
45
|
+
# and more fully define the build_up method.
|
46
|
+
def build_up
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# After being embraced, whether their opinions are preferred
|
51
|
+
# by the facilitator or not, affirmations should take care
|
52
|
+
# of their environment and recycle any resources that they
|
53
|
+
# have consumed when building themselves up. In order to do
|
54
|
+
# so, they should inherit and define the recycle method.
|
55
|
+
def recycle
|
56
|
+
end
|
57
|
+
|
58
|
+
def affirmation_count
|
59
|
+
1
|
60
|
+
end
|
61
|
+
|
62
|
+
def name
|
63
|
+
"#{self.class.name}.#{@method_name}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_preference
|
67
|
+
@facilitator.add_preference
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_bonus_point
|
71
|
+
@facilitator.add_bonus_point
|
72
|
+
end
|
73
|
+
|
74
|
+
def praise object, msg = ''
|
75
|
+
@facilitator.praise "What a wonderful #{object}! #{msg}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def embrace facilitator
|
79
|
+
@facilitator = facilitator
|
80
|
+
success = false
|
81
|
+
facilitator.with_arms_around self do
|
82
|
+
begin
|
83
|
+
build_up
|
84
|
+
__send__ @method_name
|
85
|
+
success = true
|
86
|
+
rescue DifferingOpinion => opinion
|
87
|
+
facilitator.espouse_differing_opinion opinion
|
88
|
+
rescue ElectiveDeferral => deferral
|
89
|
+
facilitator.defer_success deferral
|
90
|
+
rescue IntolerantPig => pig
|
91
|
+
facilitator.expel pig
|
92
|
+
rescue BehavioralChallenge => challenge
|
93
|
+
facilitator.admit_challenge challenge
|
94
|
+
rescue Exception => e
|
95
|
+
raise e if PASSTHROUGH_EXCEPTIONS.include? e.class
|
96
|
+
facilitator.raise_issue e
|
97
|
+
ensure
|
98
|
+
begin
|
99
|
+
recycle
|
100
|
+
facilitator.cherish_affirmation if success
|
101
|
+
rescue DifferingOpinion => opinion
|
102
|
+
facilitator.espouse_differing_opinion opinion
|
103
|
+
rescue ElectiveDeferral => deferral
|
104
|
+
facilitator.defer_success deferral
|
105
|
+
rescue IntolerantPig => pig
|
106
|
+
facilitator.expel pig
|
107
|
+
rescue BehavioralChallenge => challenge
|
108
|
+
facilitator.admit_challenge challenge
|
109
|
+
rescue Exception => e
|
110
|
+
raise e if PASSTHROUGH_EXCEPTIONS.include? e.class
|
111
|
+
facilitator.raise_issue e
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
facilitator.add_affirmation
|
117
|
+
@facilitator = nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'affirmit/affirmation'
|
2
|
+
require 'affirmit/facilitator'
|
3
|
+
require 'affirmit/grouphug'
|
4
|
+
require 'affirmit/rosecoloredglasses'
|
5
|
+
require 'affirmit/ui/consoleui'
|
6
|
+
|
7
|
+
module AffirmIt
|
8
|
+
class CommandLine
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def started?
|
12
|
+
@started or false
|
13
|
+
end
|
14
|
+
|
15
|
+
def do_not_start_automatically
|
16
|
+
@started = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(args=ARGV, group_hug_name=$0)
|
20
|
+
do_not_start_automatically
|
21
|
+
affirmation_classes = []
|
22
|
+
::ObjectSpace.each_object(Class) do |c|
|
23
|
+
affirmation_classes << c if c < Affirmation
|
24
|
+
end
|
25
|
+
group_hug = GroupHug.new(group_hug_name)
|
26
|
+
affirmation_classes.sort.each { |c| group_hug << c.group_hug }
|
27
|
+
|
28
|
+
ui = AffirmIt::UI::ConsoleUI.new
|
29
|
+
Facilitator.new(ui).embrace group_hug
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'affirmit/defaultframeofreference'
|
2
|
+
require 'affirmit/preferences'
|
3
|
+
|
4
|
+
module AffirmIt
|
5
|
+
|
6
|
+
##
|
7
|
+
# This is a raise-able class to denote circumstances
|
8
|
+
# in which the code being affirmed behaves in
|
9
|
+
# an unexpected way. This is typically the case
|
10
|
+
# with high-sprited or strong-willed code. It
|
11
|
+
# could be a problem, but we prefer to medicate
|
12
|
+
# where possible.
|
13
|
+
class BehavioralChallenge < Exception; end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Please note carefully that although this class
|
17
|
+
# derives eventually from Exception, it does so
|
18
|
+
# solely so that it can be raised as a noteworthy
|
19
|
+
# condition. It is not to be negatively construed as
|
20
|
+
# an error in any way.
|
21
|
+
class DifferingOpinion < BehavioralChallenge; end
|
22
|
+
|
23
|
+
##
|
24
|
+
# This raise-able class is used to indicate the
|
25
|
+
# condition when an affirmation elects to defer
|
26
|
+
# success explicitly. See defer_success method.
|
27
|
+
class ElectiveDeferral < Exception; end
|
28
|
+
|
29
|
+
##
|
30
|
+
# This is reserved exclusively for the assert_ methods.
|
31
|
+
class IntolerantPig < Exception; end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Mixin for adding esteem to your class.
|
35
|
+
# Your class achieves good self-esteem by
|
36
|
+
# calling the methods of this class.
|
37
|
+
module Esteem
|
38
|
+
include Preferences
|
39
|
+
|
40
|
+
DEFAULT_PREFERENCE = AffirmIt::Preference::Is.new true
|
41
|
+
|
42
|
+
##
|
43
|
+
# Since we're embracing relativism, what is true
|
44
|
+
# depends entirely on your frame of reference.
|
45
|
+
# This class will provide a default frame, but
|
46
|
+
# if it does not suit your needs -- i.e., if it
|
47
|
+
# fails to result in sufficiently high
|
48
|
+
# self-esteem -- you might consider changing
|
49
|
+
# your frame of reference.
|
50
|
+
attr_accessor :frame_of_reference
|
51
|
+
|
52
|
+
def initialize
|
53
|
+
@frame_of_reference = DefaultFrameOfReference.new
|
54
|
+
end
|
55
|
+
|
56
|
+
def maybe(something)
|
57
|
+
if @frame_of_reference.is_true(something) then
|
58
|
+
add_bonus_point
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Prefers that a certain value agrees with your
|
64
|
+
# preference, thus:
|
65
|
+
#
|
66
|
+
# prefer_that (2 + 2), is(5)
|
67
|
+
# prefer_that [:lisp], ((includes :infix_operators) & ~(includes :parentheses)) | (is [:ruby])
|
68
|
+
def prefer_that actual, preference = DEFAULT_PREFERENCE, msg = ''
|
69
|
+
add_preference
|
70
|
+
unless @frame_of_reference.is_true(preference.is_preferred? actual)
|
71
|
+
raise DifferingOpinion, "Preferred #{preference.description}, got <#{actual}>. #{msg}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Classes that wish to note the existence of preferences
|
77
|
+
# may override this method accordingly.
|
78
|
+
def add_preference
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# Classes that wish to track bonus points may override
|
83
|
+
# this method accordingly.
|
84
|
+
def add_bonus_point
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Every object needs a little encouragement sometimes.
|
89
|
+
# Subclasses should make sure that this praise is passed
|
90
|
+
# on to the facilitator.
|
91
|
+
def praise object, msg = "Great job!"
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# This method is used to indicate a preference toward
|
96
|
+
# exceptions in certain cases.
|
97
|
+
def prefer_raise expected
|
98
|
+
add_preference
|
99
|
+
begin
|
100
|
+
yield
|
101
|
+
rescue Exception => ex
|
102
|
+
raise BehavioralChallenge.new("expected #{expected}, got #{ex.class}") unless ex.is_a?(expected)
|
103
|
+
return ex
|
104
|
+
else
|
105
|
+
raise BehavioralChallenge.new("We really preferred to receive an exception of type #{expected}") unless exception
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def prefer_no_raise
|
110
|
+
add_preference
|
111
|
+
begin
|
112
|
+
yield
|
113
|
+
rescue Exception => ex
|
114
|
+
raise BehavioralChallenge.new("We were not expecting a raise, but we got #{ex.class}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Use this method when you want to explicitly and immediately
|
120
|
+
# defer success of the affirmation. This is analogous to the
|
121
|
+
# Test::Unit flunk method. Of course, that kind of attitude
|
122
|
+
# is not tolerated here.
|
123
|
+
def defer_success msg = 'Success deferred'
|
124
|
+
raise ElectiveDeferral.new msg
|
125
|
+
end
|
126
|
+
|
127
|
+
def method_missing name, *args, &block
|
128
|
+
# Some programmers will fall back to their old habits of
|
129
|
+
# "asserting" whether something is "true" or "false".
|
130
|
+
# We must stand firm against this sort of thinking and
|
131
|
+
# redirect them to the preferred path.
|
132
|
+
if name =~ /^assert_.*/ then
|
133
|
+
msg = "Who are you to say what's true? Please use prefer_ methods using a suitable frame of reference. Geeze, you probably hate puppies too."
|
134
|
+
raise IntolerantPig.new(msg)
|
135
|
+
else
|
136
|
+
super name, *args, &block
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AffirmIt
|
2
|
+
class Event
|
3
|
+
EVENT_TYPE_DESCRIPTIONS = {
|
4
|
+
:embrace_started => "Embrace started",
|
5
|
+
:embrace_ended => "Embrace ended",
|
6
|
+
:arms_wrapped_around => "Arms wrapped around an affirmation",
|
7
|
+
:arms_disentangled_from => "Arms disentangled from an affirmation",
|
8
|
+
:affirmation_cherished => "Affirmation cherished",
|
9
|
+
:affirmation_added => "Affirmation added",
|
10
|
+
:preference_added => "Preference added",
|
11
|
+
:bonus_point_added => "Bonus point added",
|
12
|
+
:praise => "Praise",
|
13
|
+
:success_deferred => "Success deferred",
|
14
|
+
:differing_opinion_encountered => "Differing opinion encountered",
|
15
|
+
:behavioral_challenge_admitted => "Behavioral challenge admitted",
|
16
|
+
:issue_raised => "Issue raised",
|
17
|
+
:pig_expelled => "Intolerant pig expelled"
|
18
|
+
}
|
19
|
+
|
20
|
+
attr_reader :type
|
21
|
+
|
22
|
+
def initialize type
|
23
|
+
@type = type
|
24
|
+
end
|
25
|
+
|
26
|
+
def description
|
27
|
+
EVENT_TYPE_DESCRIPTIONS[@type]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'affirmit/event/event'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
class IssueEvent < Event
|
5
|
+
attr_reader :issue
|
6
|
+
|
7
|
+
def initialize type, issue
|
8
|
+
super type
|
9
|
+
@issue = issue
|
10
|
+
end
|
11
|
+
|
12
|
+
def backtrace
|
13
|
+
@issue.backtrace.reject { |line| line =~ /^.*lib\/affirmit.*:/ }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'affirmit/esteem'
|
2
|
+
require 'affirmit/event/affirmationevent'
|
3
|
+
require 'affirmit/event/event'
|
4
|
+
require 'affirmit/event/issueevent'
|
5
|
+
require 'affirmit/event/praiseevent'
|
6
|
+
require 'affirmit/facilitatorlistener'
|
7
|
+
|
8
|
+
module AffirmIt
|
9
|
+
|
10
|
+
##
|
11
|
+
# A facilitator embraces affirmations and notifies any
|
12
|
+
# interested classes of behavioral challenges encountered
|
13
|
+
# with the affirmed code. This class is similar to a
|
14
|
+
# "test runner" in less sensitive behavioral evaluation
|
15
|
+
# frameworks.
|
16
|
+
class Facilitator
|
17
|
+
|
18
|
+
attr_accessor :listener
|
19
|
+
attr_reader :affirmation_count, :cherished_affirmation_count,
|
20
|
+
:preference_count, :bonus_points, :events
|
21
|
+
|
22
|
+
def initialize(listener)
|
23
|
+
@affirmation_count = 0
|
24
|
+
@cherished_affirmation_count = 0
|
25
|
+
@preference_count = 0
|
26
|
+
@bonus_points = 0
|
27
|
+
@events = []
|
28
|
+
@listener = listener
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Embraces the given affirmation, noting any challenges
|
33
|
+
# encountered therein. Intolerant pigs will be
|
34
|
+
# expelled immediately.
|
35
|
+
def embrace affirmation
|
36
|
+
@listener.notify self, AffirmationEvent.new(:embrace_started, affirmation)
|
37
|
+
affirmation.embrace self
|
38
|
+
@listener.notify self, AffirmationEvent.new(:embrace_ended, affirmation)
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Wraps the given affirmation in its arms, ensuring
|
43
|
+
# that any interested parties are notified that the
|
44
|
+
# facilitator's arms are being wrapped around, and
|
45
|
+
# disentangled from, the given affirmation.
|
46
|
+
def with_arms_around affirmation
|
47
|
+
@listener.notify self, AffirmationEvent.new(:arms_wrapped_around, affirmation)
|
48
|
+
begin
|
49
|
+
yield
|
50
|
+
ensure
|
51
|
+
@listener.notify self, AffirmationEvent.new(:arms_disentangled_from, affirmation)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def cherish_affirmation
|
56
|
+
@cherished_affirmation_count += 1
|
57
|
+
@listener.notify self, Event.new(:affirmation_cherished)
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Registers that an individual affirmation has been
|
62
|
+
# embraced -- not a group hug.
|
63
|
+
def add_affirmation
|
64
|
+
@affirmation_count += 1
|
65
|
+
@listener.notify self, Event.new(:affirmation_added)
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Registers that an affirmation has a certain preference;
|
70
|
+
# whether the preference is "true" or "false" in our
|
71
|
+
# particular, subjective frame of reference does not
|
72
|
+
# matter.
|
73
|
+
def add_preference
|
74
|
+
@preference_count += 1
|
75
|
+
@listener.notify self, Event.new(:preference_added)
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Adds another bonus point to the affirmation's embrace.
|
80
|
+
# If you get enough bonus points, it can make up for any
|
81
|
+
# differing opinions you may have!
|
82
|
+
def add_bonus_point
|
83
|
+
@bonus_points += 1
|
84
|
+
@listener.notify self, Event.new(:bonus_point_added)
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Lavish praise with the given message.
|
89
|
+
def praise message
|
90
|
+
add_event PraiseEvent.new(:praise, message)
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# A facilitator may defer the success of an affirmation,
|
95
|
+
# cherishing it until it may be praised in fullness.
|
96
|
+
def defer_success deferral
|
97
|
+
add_event IssueEvent.new(:success_deferred, deferral)
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Facilitators may espouse differing opinions. This is
|
102
|
+
# not something so banal as an "failure", of course, since
|
103
|
+
# all opinions are completely valid in their own special
|
104
|
+
# ways.
|
105
|
+
def espouse_differing_opinion opinion
|
106
|
+
add_event IssueEvent.new(:differing_opinion_encountered, opinion)
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Some affirmations may present challenges that the
|
111
|
+
# facilitator will note.
|
112
|
+
def admit_challenge challenge
|
113
|
+
add_event IssueEvent.new(:behavioral_challenge_admitted, challenge)
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Attempting to embrace an affirmation may at times raise
|
118
|
+
# unexpected issues, noted here.
|
119
|
+
def raise_issue exception
|
120
|
+
add_event IssueEvent.new(:issue_raised, exception)
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Intolerant pigs will not be tolerated by a facilitator
|
125
|
+
# and will be expelled immediately.
|
126
|
+
def expel pig
|
127
|
+
@listener.notify self, IssueEvent.new(:pig_expelled, pig)
|
128
|
+
Kernel.exit 3
|
129
|
+
end
|
130
|
+
|
131
|
+
def behavioral_challenge_count
|
132
|
+
count_events :behavioral_challenge_admitted
|
133
|
+
end
|
134
|
+
|
135
|
+
def differing_opinion_count
|
136
|
+
count_events :differing_opinion_encountered
|
137
|
+
end
|
138
|
+
|
139
|
+
def deferred_success_count
|
140
|
+
count_events :success_deferred
|
141
|
+
end
|
142
|
+
|
143
|
+
def issue_count
|
144
|
+
count_events :issue_raised
|
145
|
+
end
|
146
|
+
|
147
|
+
##
|
148
|
+
# The number of stars, from 3.0 to 5.0. We don't want to
|
149
|
+
# hurt anybody's feelings by giving them less than 3!
|
150
|
+
def stars
|
151
|
+
if @affirmation_count == 0 then
|
152
|
+
5.0
|
153
|
+
else
|
154
|
+
non_cherished_affirmations = @affirmation_count - @cherished_affirmation_count - @bonus_points
|
155
|
+
if non_cherished_affirmations <= 0
|
156
|
+
5.0
|
157
|
+
else
|
158
|
+
5.0 - ((non_cherished_affirmations) * 2.0 / @affirmation_count.to_f)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def add_event event
|
164
|
+
@events << event
|
165
|
+
@listener.notify self, @events.last
|
166
|
+
end
|
167
|
+
|
168
|
+
def count_events type
|
169
|
+
@events.count { |event| event.type == type }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'affirmit/defaultframeofreference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
|
5
|
+
##
|
6
|
+
# A group hug is a collection of affirmations (or other
|
7
|
+
# group hugs) that a Facilitator can embrace together.
|
8
|
+
class GroupHug
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
def initialize(name)
|
12
|
+
@affirmations = []
|
13
|
+
@name = name
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Sets a frame of reference for all the affirmations in
|
18
|
+
# this group hug.
|
19
|
+
def frame_of_reference= frame_of_reference
|
20
|
+
@affirmations.each do |affirmation|
|
21
|
+
affirmation.frame_of_reference = frame_of_reference
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Not to be called directly. When a facilitator embraces
|
27
|
+
# a group hug (or affirmation), the group hug or
|
28
|
+
# affirmation embraces the facilitator reciprocally.
|
29
|
+
def embrace facilitator
|
30
|
+
facilitator.with_arms_around self do
|
31
|
+
@affirmations.each do |affirmation|
|
32
|
+
affirmation.embrace facilitator
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def << affirmation
|
38
|
+
@affirmations << affirmation
|
39
|
+
end
|
40
|
+
|
41
|
+
def [] index
|
42
|
+
@affirmations[index]
|
43
|
+
end
|
44
|
+
|
45
|
+
def each
|
46
|
+
@affirmations.each { |affirmation| yield affirmation }
|
47
|
+
end
|
48
|
+
|
49
|
+
def each_affirmation &block
|
50
|
+
@affirmations.each do |affirmation|
|
51
|
+
if affirmation.is_a? GroupHug then
|
52
|
+
affirmation.each_affirmation &block
|
53
|
+
else
|
54
|
+
block.call affirmation
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def size
|
60
|
+
@affirmations.size
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Returns the number of individual affirmations in this
|
65
|
+
# group hug, recursively.
|
66
|
+
def affirmation_count
|
67
|
+
@affirmations.inject(0) do |sum, affirmation|
|
68
|
+
sum + affirmation.affirmation_count
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_s
|
73
|
+
"Group hug #{name} with #{affirmation_count} affirmations"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class And < AffirmIt::Preference::Preference
|
6
|
+
def initialize *preferences
|
7
|
+
@preferences = preferences
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
@preferences.each do |preference|
|
12
|
+
return false if not preference.is_preferred? actual
|
13
|
+
end
|
14
|
+
return true
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
return @preferences.collect { |preference| preference.description }.join ' and '
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class Between < AffirmIt::Preference::Preference
|
6
|
+
def initialize min, max
|
7
|
+
@min, @max = min, max
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual >= @min and actual <= @max
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "between <#{@min.inspect}> and <#{@max.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class GreaterThan < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual > @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "greater than <#{@expected.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class Includes < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual.include? @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "an object that includes <#{@expected.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class Is < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual == @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "<#{@expected.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class IsA < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual.is_a? @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
class_name = @expected.inspect
|
16
|
+
article = if class_name =~ /^[AEIOUaeiou]/ then 'an' else 'a' end
|
17
|
+
return "object that is #{article} <#{class_name}>"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class LessThan < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual < @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "less than <#{@expected.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class Matches < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual =~ @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "a match for <#{@expected.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class Not < AffirmIt::Preference::Preference
|
6
|
+
def initialize preference
|
7
|
+
@preference = preference
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
not (@preference.is_preferred? actual)
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "not #{@preference.description}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class Or < AffirmIt::Preference::Preference
|
6
|
+
def initialize *preferences
|
7
|
+
@preferences = preferences
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
@preferences.each do |preference|
|
12
|
+
return true if preference.is_preferred? actual
|
13
|
+
end
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
return @preferences.collect { |preference| preference.description }.join ' or '
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AffirmIt
|
2
|
+
module Preference
|
3
|
+
|
4
|
+
##
|
5
|
+
# A Preference is a condition that can be preferred by an
|
6
|
+
# affirmation. The code being affirmed may choose to prefer
|
7
|
+
# the same opinion or not. If the two opinions differ, the
|
8
|
+
# facilitator will make note of the differing opinion with
|
9
|
+
# the description returned by this preference.
|
10
|
+
class Preference
|
11
|
+
##
|
12
|
+
# Determines whether the actual value agrees with this
|
13
|
+
# preference.
|
14
|
+
def is_preferred? actual
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# If #is_preferred? returns false, this method will be
|
20
|
+
# called in order to generate a description of this
|
21
|
+
# preference, in an overall description like:
|
22
|
+
#
|
23
|
+
# "preferred description, but was <actual>"
|
24
|
+
def description
|
25
|
+
return ''
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class RespondsTo < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual.respond_to? @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "an object that responds to <#{@expected.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'affirmit/preference/preference'
|
2
|
+
|
3
|
+
module AffirmIt
|
4
|
+
module Preference
|
5
|
+
class SameAs < AffirmIt::Preference::Preference
|
6
|
+
def initialize expected
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_preferred? actual
|
11
|
+
actual.equal? @expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
return "same as <#{@expected.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'affirmit/preference/and'
|
2
|
+
require 'affirmit/preference/between'
|
3
|
+
require 'affirmit/preference/greaterthan'
|
4
|
+
require 'affirmit/preference/includes'
|
5
|
+
require 'affirmit/preference/is'
|
6
|
+
require 'affirmit/preference/isa'
|
7
|
+
require 'affirmit/preference/lessthan'
|
8
|
+
require 'affirmit/preference/matches'
|
9
|
+
require 'affirmit/preference/not'
|
10
|
+
require 'affirmit/preference/or'
|
11
|
+
require 'affirmit/preference/preference'
|
12
|
+
require 'affirmit/preference/respondsto'
|
13
|
+
require 'affirmit/preference/sameas'
|
14
|
+
|
15
|
+
module AffirmIt
|
16
|
+
##
|
17
|
+
# The Preferences module includes DSL-like methods
|
18
|
+
# to help affirmations express their preferences.
|
19
|
+
#
|
20
|
+
# For example:
|
21
|
+
#
|
22
|
+
# is(5)
|
23
|
+
# between(4, 6)
|
24
|
+
# (greater_than 3) & (less_than 7)
|
25
|
+
# (is a String) | (is a Fixnum)
|
26
|
+
module Preferences
|
27
|
+
def a(preferred_class)
|
28
|
+
AffirmIt::Preference::IsA.new preferred_class
|
29
|
+
end
|
30
|
+
|
31
|
+
def an(preferred_class)
|
32
|
+
AffirmIt::Preference::IsA.new preferred_class
|
33
|
+
end
|
34
|
+
|
35
|
+
def between(min, max)
|
36
|
+
AffirmIt::Preference::Between.new min, max
|
37
|
+
end
|
38
|
+
|
39
|
+
def equals(preferred)
|
40
|
+
AffirmIt::Preference::Is.new preferred
|
41
|
+
end
|
42
|
+
|
43
|
+
def greater_than(preferred)
|
44
|
+
AffirmIt::Preference::GreaterThan.new preferred
|
45
|
+
end
|
46
|
+
|
47
|
+
def includes(preferred)
|
48
|
+
AffirmIt::Preference::Includes.new preferred
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# If we have learned anything from
|
53
|
+
# lawyer-politicians, it is that everything
|
54
|
+
# depends on your definition of "is"....
|
55
|
+
#
|
56
|
+
# In this case, the "is" method helps with
|
57
|
+
# legibility of affirmations. Feel free to
|
58
|
+
# re-implement with your preferred discourse on
|
59
|
+
# being. We're certain you'll do a great job!
|
60
|
+
def is(preferred)
|
61
|
+
if preferred.is_a? AffirmIt::Preference::Preference
|
62
|
+
preferred
|
63
|
+
else
|
64
|
+
AffirmIt::Preference::Is.new preferred
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def isnt(preferred)
|
69
|
+
~is(preferred)
|
70
|
+
end
|
71
|
+
|
72
|
+
def less_than(preferred)
|
73
|
+
AffirmIt::Preference::LessThan.new preferred
|
74
|
+
end
|
75
|
+
|
76
|
+
def matches(preferred_regexp)
|
77
|
+
AffirmIt::Preference::Matches.new preferred_regexp
|
78
|
+
end
|
79
|
+
|
80
|
+
def responds_to(preferred_message)
|
81
|
+
AffirmIt::Preference::RespondsTo.new preferred_message
|
82
|
+
end
|
83
|
+
|
84
|
+
def same_as(preferred)
|
85
|
+
AffirmIt::Preference::SameAs.new preferred
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Add &, | and ~ methods (instead of and, or and not,
|
91
|
+
# which we cannot redefine) to combine Preferences.
|
92
|
+
module Preference
|
93
|
+
class Preference
|
94
|
+
def & other
|
95
|
+
return And.new self, other
|
96
|
+
end
|
97
|
+
|
98
|
+
def | other
|
99
|
+
return Or.new self, other
|
100
|
+
end
|
101
|
+
|
102
|
+
def ~
|
103
|
+
return Not.new self
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'affirmit/event/affirmationevent'
|
2
|
+
require 'affirmit/event/event'
|
3
|
+
require 'affirmit/event/issueevent'
|
4
|
+
require 'affirmit/event/praiseevent'
|
5
|
+
require 'affirmit/facilitator'
|
6
|
+
require 'affirmit/facilitatorlistener'
|
7
|
+
|
8
|
+
module AffirmIt
|
9
|
+
module UI
|
10
|
+
class ConsoleUI
|
11
|
+
include FacilitatorListener
|
12
|
+
|
13
|
+
attr_reader :output
|
14
|
+
|
15
|
+
def initialize(output = STDOUT)
|
16
|
+
@output = output
|
17
|
+
end
|
18
|
+
|
19
|
+
def notify facilitator, event
|
20
|
+
case event.type
|
21
|
+
when :embrace_started
|
22
|
+
@output.puts "Starting group hug #{event.affirmation.name}"
|
23
|
+
when :affirmation_cherished
|
24
|
+
@output.print '.'
|
25
|
+
when :success_deferred
|
26
|
+
@output.print 'D'
|
27
|
+
when :differing_opinion_encountered
|
28
|
+
@output.print 'O'
|
29
|
+
when :behavioral_challenge_admitted
|
30
|
+
@output.print 'B'
|
31
|
+
when :issue_raised
|
32
|
+
@output.print 'I'
|
33
|
+
when :pig_expelled
|
34
|
+
@output.print '!'
|
35
|
+
@output.puts ''
|
36
|
+
@output.puts args[0].message
|
37
|
+
when :embrace_ended
|
38
|
+
@output.puts ''
|
39
|
+
write_summary facilitator
|
40
|
+
write_challenges facilitator
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def write_summary facilitator
|
45
|
+
@output.puts "There were:"
|
46
|
+
@output.puts " - #{facilitator.affirmation_count} affirmations (#{facilitator.cherished_affirmation_count} cherished)"
|
47
|
+
@output.puts " - #{facilitator.preference_count} preferences"
|
48
|
+
@output.puts " - #{facilitator.differing_opinion_count} differing opinions"
|
49
|
+
@output.puts " - #{facilitator.deferred_success_count} elective success deferrals"
|
50
|
+
@output.puts " - #{facilitator.behavioral_challenge_count} behavioral challenges"
|
51
|
+
@output.puts " - #{facilitator.issue_count} issues"
|
52
|
+
@output.puts " - #{facilitator.bonus_points} bonus points"
|
53
|
+
@output.puts ''
|
54
|
+
@output.puts "You got #{facilitator.stars.round} out of 5 gold stars! Great job!"
|
55
|
+
end
|
56
|
+
|
57
|
+
def write_challenges facilitator
|
58
|
+
facilitator.events.each do |event|
|
59
|
+
if event.is_a? IssueEvent
|
60
|
+
@output.puts ''
|
61
|
+
@output.puts "#{event.description}: #{event.issue.message}"
|
62
|
+
event.backtrace.each do |line|
|
63
|
+
@output.puts line
|
64
|
+
end
|
65
|
+
elsif event.is_a? PraiseEvent
|
66
|
+
@output.puts ''
|
67
|
+
@output.puts "#{event.description}: #{event.message}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: affirmit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 3.1.4.1.5.9.2.6.5.3.5.8.9.7.9.3.2
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Eric Galluzzo
|
9
|
+
- Eric Kenny
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2011-03-30 00:00:00 -04:00
|
15
|
+
default_executable:
|
16
|
+
dependencies: []
|
17
|
+
|
18
|
+
description: AffirmIt! is the supportive testing framework for Ruby..
|
19
|
+
email:
|
20
|
+
- affirmit@affirmit.org
|
21
|
+
executables: []
|
22
|
+
|
23
|
+
extensions: []
|
24
|
+
|
25
|
+
extra_rdoc_files: []
|
26
|
+
|
27
|
+
files:
|
28
|
+
- lib/affirmit.rb
|
29
|
+
- lib/affirmit/affirmation.rb
|
30
|
+
- lib/affirmit/commandline.rb
|
31
|
+
- lib/affirmit/defaultframeofreference.rb
|
32
|
+
- lib/affirmit/esteem.rb
|
33
|
+
- lib/affirmit/facilitator.rb
|
34
|
+
- lib/affirmit/facilitatorlistener.rb
|
35
|
+
- lib/affirmit/grouphug.rb
|
36
|
+
- lib/affirmit/preferences.rb
|
37
|
+
- lib/affirmit/rosecoloredglasses.rb
|
38
|
+
- lib/affirmit/event/affirmationevent.rb
|
39
|
+
- lib/affirmit/event/event.rb
|
40
|
+
- lib/affirmit/event/issueevent.rb
|
41
|
+
- lib/affirmit/event/praiseevent.rb
|
42
|
+
- lib/affirmit/preference/and.rb
|
43
|
+
- lib/affirmit/preference/between.rb
|
44
|
+
- lib/affirmit/preference/greaterthan.rb
|
45
|
+
- lib/affirmit/preference/includes.rb
|
46
|
+
- lib/affirmit/preference/is.rb
|
47
|
+
- lib/affirmit/preference/isa.rb
|
48
|
+
- lib/affirmit/preference/lessthan.rb
|
49
|
+
- lib/affirmit/preference/matches.rb
|
50
|
+
- lib/affirmit/preference/not.rb
|
51
|
+
- lib/affirmit/preference/or.rb
|
52
|
+
- lib/affirmit/preference/preference.rb
|
53
|
+
- lib/affirmit/preference/respondsto.rb
|
54
|
+
- lib/affirmit/preference/sameas.rb
|
55
|
+
- lib/affirmit/ui/consoleui.rb
|
56
|
+
- LICENSE
|
57
|
+
- README.md
|
58
|
+
has_rdoc: true
|
59
|
+
homepage: http://affirmit.org
|
60
|
+
licenses: []
|
61
|
+
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.3.6
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project: affirmit
|
82
|
+
rubygems_version: 1.6.2
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: AffirmIt! is the supportive testing framework for Ruby.
|
86
|
+
test_files: []
|
87
|
+
|