state_shifter 0.8.1 → 1.0.3

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.
@@ -2,51 +2,63 @@ module StateShifter
2
2
  module Definition
3
3
  class Contents
4
4
 
5
- attr_accessor :states, :initial_state, :events, :on_transition_proc
5
+ attr_accessor :states, :initial_state, :events, :state_tags, :on_transition_proc
6
6
 
7
7
  def initialize &definition
8
- @states = {}
9
- @events = {}
8
+ @states = {}
9
+ @events = {}
10
+ @state_tags = {}
10
11
  instance_eval &definition if block_given?
11
12
  end
12
13
 
13
14
  def state name, &events_and_stuff
14
- this_state = State.new(name)
15
- @initial_state = this_state if @states.empty? # first state declared is the initial one
16
-
17
- raise ::StateShifter::RedifiningState, this_state.name if @states.has_key?(this_state.name.to_sym)
18
-
15
+ if @states.empty? # first state declared is the initial one
16
+ this_state = State.new(name, true)
17
+ @initial_state = this_state
18
+ else
19
+ this_state = State.new(name)
20
+ end
21
+
22
+ raise RedifiningState, this_state.name if @states.has_key?(this_state.name.to_sym)
23
+
19
24
  @states[this_state.name.to_sym] = this_state
20
25
  @current_state = this_state
21
26
  instance_eval &events_and_stuff if events_and_stuff
22
27
  end
23
28
 
29
+ def tags *names
30
+ names.each do |name|
31
+ @state_tags[name] ||= []
32
+ @state_tags[name] << @current_state.name
33
+ end
34
+ end
35
+
24
36
  def event hash_or_sym, hash=nil
25
37
  this_event =
26
38
  if hash.nil?
27
39
  if hash_or_sym.is_a?(Symbol)
28
40
  # looping event
29
41
  event_name = hash_or_sym
30
-
42
+
31
43
  Event.new @current_state.name.to_sym, event_name
32
44
  else
33
45
  # normal event
34
46
  event_guards = hash_or_sym.delete(:if)
35
47
  event_name = hash_or_sym.keys.first
36
48
  event_next_state = hash_or_sym[event_name.to_sym]
37
-
49
+
38
50
  Event.new @current_state.name.to_sym, event_name, event_next_state, event_guards
39
51
  end
40
52
  else
41
53
  event_guards = hash.delete(:if)
42
54
  event_name = hash_or_sym
43
55
  event_callback = hash.delete(:call)
44
-
56
+
45
57
  Event.new @current_state.name.to_sym, event_name, @current_state.name.to_sym, event_guards, event_callback
46
58
  end
47
59
 
48
- raise ::StateShifter::RedifiningEvent, this_event.name if @events.has_key?(this_event.name.to_sym)
49
-
60
+ raise RedifiningEvent, this_event.name if @events.has_key?(this_event.name.to_sym)
61
+
50
62
  @events[this_event.name.to_sym] = this_event
51
63
  @current_state.events[event_name.to_sym] = this_event
52
64
  end
@@ -56,7 +68,7 @@ module StateShifter
56
68
  @current_state.entry_callback = proc_contents
57
69
  else
58
70
  @current_state.entry_callback = event_name
59
- @current_state.entry_callback_args = ( event_args.size == 1 ? event_args.first : event_args )
71
+ @current_state.entry_callback_args = ( event_args.size == 1 ? event_args.first : event_args ) unless event_args.empty?
60
72
  end
61
73
  end
62
74
 
@@ -7,11 +7,11 @@ module StateShifter
7
7
  end
8
8
 
9
9
  def get_current_state
10
- instance_variable_defined?(:@current_state) ? @current_state : state_machine_definition.initial_state.name.to_sym
10
+ instance_variable_defined?(:@current_state) ? @current_state.to_sym : state_machine_definition.initial_state.name.to_sym
11
11
  end
12
12
 
13
13
  def set_current_state value
14
- @current_state = value
14
+ @current_state = value.to_sym
15
15
  end
16
16
 
17
17
  def state_machine_definition
@@ -39,16 +39,13 @@ module StateShifter
39
39
  end
40
40
 
41
41
  def names_for what
42
- state_machine_definition.send(what).collect {|name, definition| name }
42
+ state_machine_definition.send(what).collect {|name, definition| name.to_sym }
43
43
  end
44
44
 
45
45
  def check_event_callbacks event_name
46
46
  event_def = state_machine_definition.get(:event, event_name)
47
- begin
48
- self.send event_def.callback
49
- rescue NoMethodError
50
- raise ::StateShifter::CallbackMethodNotDefined, event_def.callback
51
- end
47
+
48
+ self.send event_def.callback
52
49
  end
53
50
 
54
51
  def current_state_def
@@ -60,14 +57,16 @@ module StateShifter
60
57
 
61
58
  if proc_or_method_name.is_a?(Symbol)
62
59
  method_args = current_state_def.entry_callback_args
63
- begin
60
+
61
+ if method_args
64
62
  self.send proc_or_method_name, method_args
65
- rescue NoMethodError
66
- raise ::StateShifter::CallbackMethodNotDefined, proc_or_method_name
63
+ else
64
+ self.send proc_or_method_name
67
65
  end
66
+
68
67
  else
69
68
  self.instance_exec(old_state, trigger.to_sym, &proc_or_method_name)
70
- end
69
+ end
71
70
  end
72
71
 
73
72
  def transition args
@@ -75,20 +74,20 @@ module StateShifter
75
74
 
76
75
  # BOOP!
77
76
  old_state = get_current_state
78
- set_current_state args[:to].to_sym
77
+ set_current_state args[:to]
79
78
  #
80
79
 
81
- check_event_callbacks(args[:trigger]) if state_machine_definition.get(:event, args[:trigger]).has_callback?
80
+ self.instance_exec(old_state, get_current_state, args[:trigger].to_sym, (Time.now - _start), &state_machine_definition.on_transition_proc) if state_machine_definition.has_on_transition_proc?
82
81
 
83
82
  call_state_entry_callback(args[:trigger], old_state) if current_state_def.has_entry_callback?
84
-
85
- self.instance_exec(old_state, get_current_state, args[:trigger].to_sym, (Time.now - _start), &state_machine_definition.on_transition_proc) if state_machine_definition.has_on_transition_proc?
83
+
84
+ check_event_callbacks(args[:trigger]) if state_machine_definition.get(:event, args[:trigger]).has_callback?
86
85
 
87
86
  true
88
87
  end
89
88
 
90
89
  def halt message
91
- raise ::StateShifter::TransitionHalted, message
90
+ raise TransitionHalted, message
92
91
  end
93
92
 
94
93
  def check_guards event_name
@@ -99,7 +98,7 @@ module StateShifter
99
98
  begin
100
99
  return false, guard unless self.send(guard.to_sym)
101
100
  rescue NoMethodError
102
- raise ::StateShifter::GuardMethodUndefined, guard
101
+ raise GuardMethodUndefined, guard
103
102
  end
104
103
  end
105
104
  true
@@ -8,6 +8,7 @@ module StateShifter
8
8
  if Object.const_defined?(:ActiveRecord)
9
9
  if klass < ActiveRecord::Base
10
10
  klass.send :include, ActiveRecordIntegrationMethods
11
+ klass.send :_include_state_scopes=, true
11
12
  klass.before_validation :write_initial_state
12
13
  end
13
14
  end
@@ -0,0 +1,38 @@
1
+ module StateShifter
2
+
3
+ class Draw
4
+
5
+ gem 'ruby-graphviz', '>=0.9.0'
6
+ require 'graphviz'
7
+
8
+ def self.graph klasses, options
9
+ klasses.split(',').each do |klass|
10
+ this_class = eval(klass)
11
+
12
+ graph = GraphViz.new(:G, :rankdir => options[:orientation] == 'landscape' ? 'LR' : 'TB')
13
+
14
+ this_class.state_machine_definition.states.each do |state_name, state_definition|
15
+ node = state_definition.draw(graph, options)
16
+ node.fontname = options[:font] if options[:font]
17
+ end
18
+
19
+ this_class.state_machine_definition.events.each do |event_name, event_definition|
20
+ edge = event_definition.draw(graph, options)
21
+ edge.fontname = options[:font] if options[:font]
22
+ end
23
+
24
+ graphvizVersion = Constants::RGV_VERSION.split('.')
25
+
26
+ if graphvizVersion[0] == '0' && graphvizVersion[1] == '9' && graphvizVersion[2] == '0'
27
+ output_options = {:output => options[:format], :file => options[:output_filename]}
28
+ else
29
+ output_options = {options[:format] => options[:output_filename]}
30
+ end
31
+
32
+ graph.output(output_options)
33
+ end
34
+ end
35
+ end
36
+
37
+ end
38
+
@@ -18,5 +18,10 @@ module StateShifter
18
18
  !@callback.nil?
19
19
  end
20
20
 
21
+ def draw(graph, options = {})
22
+ to = @to ? @to : @from
23
+ graph.add_edges(@from.to_s, to.to_s, :label => @name.to_s)
24
+ end
25
+
21
26
  end
22
27
  end
@@ -0,0 +1,11 @@
1
+ require 'rails'
2
+
3
+ module StateShifter
4
+ class Railtie < ::Rails::Railtie
5
+
6
+ rake_tasks do
7
+ load 'tasks/state_shifter.rake'
8
+ end
9
+
10
+ end
11
+ end
@@ -1,21 +1,43 @@
1
1
  module StateShifter
2
2
 
3
3
  class State
4
-
5
- attr_reader :name, :events
4
+
5
+ attr_reader :name, :events, :initial
6
6
  attr_accessor :entry_callback, :entry_callback_args
7
7
 
8
- def initialize name
8
+ def initialize name, initial=false
9
9
  @name = name
10
10
  @events = {}
11
+ @initial = initial
11
12
  @entry_callback = nil
12
- @entry_callback_args = []
13
+ @entry_callback_args = nil
13
14
  end
14
15
 
15
16
  def has_entry_callback?
16
17
  !@entry_callback.nil?
17
18
  end
18
19
 
20
+ def initial?
21
+ @initial
22
+ end
23
+
24
+ def final?
25
+ @events.empty?
26
+ end
27
+
28
+ def draw graph, options
29
+ node = graph.add_nodes(@name.to_s,
30
+ :label => @name.to_s,
31
+ :width => '1',
32
+ :height => '1',
33
+ :shape => final? ? 'doublecircle' : 'ellipse'
34
+ )
35
+
36
+ graph.add_edges(graph.add_nodes('starting_state', :shape => 'point'), node) if initial?
37
+
38
+ node
39
+ end
40
+
19
41
  end
20
42
 
21
43
  end
data/lib/state_shifter.rb CHANGED
@@ -5,12 +5,18 @@ require 'state_shifter/definition/contents'
5
5
  require 'state_shifter/definition/class_methods'
6
6
  require 'state_shifter/definition/instance_methods'
7
7
  require 'state_shifter/definition/active_record_integration_methods'
8
+ require 'state_shifter/draw'
8
9
 
9
- class ::StateShifter::TransitionHalted < Exception ; end
10
- class ::StateShifter::GuardMethodUndefined < Exception ; end
11
- class ::StateShifter::GuardNotSatisfied < Exception ; end
12
- class ::StateShifter::CallbackMethodNotDefined < Exception ; end
13
- class ::StateShifter::RedifiningEvent < Exception ; end
14
- class ::StateShifter::RedifiningState < Exception ; end
15
- class ::StateShifter::PersistenceAttributeAlreadyDefined < Exception ; end
10
+ require 'state_shifter/railtie' if defined?(Rails)
16
11
 
12
+ module StateShifter
13
+
14
+ class TransitionHalted < Exception ; end
15
+ class GuardMethodUndefined < Exception ; end
16
+ class GuardNotSatisfied < Exception ; end
17
+ class CallbackMethodNotDefined < Exception ; end
18
+ class RedifiningEvent < Exception ; end
19
+ class RedifiningState < Exception ; end
20
+ class PersistenceAttributeAlreadyDefined < Exception ; end
21
+
22
+ end
@@ -0,0 +1,26 @@
1
+ namespace :state_shifter do
2
+ desc 'Draws state machines using GraphViz (options: CLASS=User,Vehicle; FONT=Arial; FORMAT=png; ORIENTATION=portrait; OUTPUT_FILENAME=filename)'
3
+ task :draw do
4
+
5
+ unless ENV['CLASS']
6
+ puts 'you need to specify at least one CLASS'
7
+ exit 1
8
+ end
9
+
10
+ options = {}
11
+
12
+ options[:format] = ENV['FORMAT'] || 'png'
13
+ options[:output_filename] = ENV['OUTPUT_FILENAME'] || "#{ENV['CLASS']}.#{options[:format]}"
14
+ options[:font] = ENV['FONT'] || 'Arial'
15
+ options[:orientation] = ENV['ORIENTATION'] || 'portrait'
16
+
17
+ if defined?(Rails)
18
+ Rake::Task['environment'].invoke
19
+ else
20
+ $:.unshift(File.dirname(__FILE__) + '/..')
21
+ require 'state_shifter'
22
+ end
23
+
24
+ StateShifter::Draw.graph(ENV['CLASS'], options)
25
+ end
26
+ end
@@ -5,7 +5,7 @@ require_relative '../examples/review'
5
5
  require_relative '../examples/review_custom_persistence'
6
6
 
7
7
  shared_examples_for 'a simple state machine' do
8
-
8
+
9
9
  before(:each) do
10
10
  @state_machine = described_class.new
11
11
  @state_machine.save if @state_machine.class < ActiveRecord::Base
@@ -20,6 +20,8 @@ shared_examples_for 'a simple state machine' do
20
20
  @state_machine.initial_state.should == :new
21
21
  @state_machine.current_state.should == :new
22
22
 
23
+ @state_machine.current_state_def.initial?.should be_true
24
+
23
25
  @state_machine.submit
24
26
  @state_machine.initial_state.should == :new
25
27
 
@@ -78,6 +80,8 @@ shared_examples_for 'a simple state machine' do
78
80
  @state_machine.next_states.should == [:awaiting_review]
79
81
  @state_machine.transitionable_states.should == [:awaiting_review]
80
82
 
83
+ @state_machine.current_state_def.final?.should be_false
84
+
81
85
  @state_machine.submit!
82
86
  @state_machine.next_states.should == [:being_reviewed]
83
87
  @state_machine.transitionable_states.should == [:being_reviewed]
@@ -89,6 +93,8 @@ shared_examples_for 'a simple state machine' do
89
93
  @state_machine.accept
90
94
  @state_machine.next_states.should == []
91
95
  @state_machine.transitionable_states.should == []
96
+
97
+ @state_machine.current_state_def.final?.should be_true
92
98
  end
93
99
 
94
100
  it 'should respect proper transition precedence' do
@@ -99,7 +105,7 @@ shared_examples_for 'a simple state machine' do
99
105
  end
100
106
 
101
107
  describe Simple do
102
-
108
+
103
109
  it_should_behave_like 'a simple state machine'
104
110
 
105
111
  end
@@ -127,24 +133,12 @@ describe 'Advanced state machine functionality' do
127
133
  end
128
134
 
129
135
  it 'should complain about undefined guards' do
130
- advanced = Advanced.new
131
- lambda { advanced.can_start_date_reached?}.should raise_error(StateShifter::GuardMethodUndefined, 'start_date_reached?')
132
- end
133
-
134
- it 'should complain about undefined callbacks on state entry' do
135
- advanced = Advanced.new
136
- advanced.forced_start!
137
-
138
- lambda { advanced.deadline_reached }.should raise_error(StateShifter::CallbackMethodNotDefined, 'send_notification_to_organizers')
139
- end
140
-
141
- it 'should complain about looping event callbacks not being defined' do
142
- lambda { @advanced.start_date_changed }.should raise_error(StateShifter::CallbackMethodNotDefined, 'handle_start_date_changed')
136
+ lambda { @advanced.can_start_date_reached?}.should raise_error(StateShifter::GuardMethodUndefined, 'start_date_reached?')
143
137
  end
144
138
 
145
139
  it 'should call looping event callbacks' do
146
140
  @advanced.stub!(:handle_start_date_changed)
147
-
141
+
148
142
  @advanced.should_receive(:handle_start_date_changed)
149
143
  @advanced.start_date_changed
150
144
  end
@@ -155,7 +149,7 @@ describe 'Advanced state machine functionality' do
155
149
  @advanced.forced_start
156
150
 
157
151
  # method name only
158
- @advanced.should_receive(:send_notification_to_organizers)
152
+ @advanced.should_receive(:send_notification_to_organizers).with(no_args())
159
153
  @advanced.deadline_reached!
160
154
  end
161
155
 
@@ -181,6 +175,12 @@ describe 'Advanced state machine functionality' do
181
175
  @advanced.forced_start!
182
176
  end
183
177
 
178
+ it 'the on_transition callback should work in the proper order' do
179
+ @advanced.should_receive(:benchmark).ordered.with(:initialized, :preparing, :event_associated!, an_instance_of(Float)).and_return(nil)
180
+ @advanced.should_receive(:benchmark).ordered.with(:preparing, :running, :all_done!, an_instance_of(Float)).and_return(nil)
181
+ @advanced.event_associated!
182
+ end
183
+
184
184
  end
185
185
 
186
186
  describe Review do
@@ -197,8 +197,58 @@ describe Review do
197
197
  end
198
198
  end
199
199
 
200
+ after(:each) do
201
+ described_class.destroy_all
202
+ end
203
+
200
204
  it_should_behave_like 'a simple state machine'
201
205
 
206
+ it "should tolerate strings as state names" do
207
+ state_machine = described_class.new
208
+ state_machine.save
209
+
210
+ state_machine.current_state.should == :new
211
+ state_machine.update_attribute(:current_state, "new")
212
+
213
+ state_machine.new?.should be_true
214
+
215
+ state_machine.submit
216
+ state_machine.initial_state.should == :new
217
+
218
+ state_machine.current_state.should == :awaiting_review
219
+ end
220
+
221
+ it "should have tag methods" do
222
+ described_class.reviewable_states.should eq([:new, :awaiting_review, :being_reviewed])
223
+
224
+ state_machine = described_class.new
225
+ state_machine.save
226
+
227
+ state_machine.reviewable?.should be_true
228
+ state_machine.processing?.should be_false
229
+
230
+ state_machine.submit
231
+ state_machine.reviewable?.should be_true
232
+ state_machine.processing?.should be_true
233
+
234
+ state_machine.review!
235
+ state_machine.reviewable?.should be_true
236
+ state_machine.processing?.should be_true
237
+
238
+ state_machine.accept!
239
+ state_machine.reviewable?.should be_false
240
+ state_machine.processing?.should be_false
241
+ end
242
+
243
+ it "should have state scopes" do
244
+ state_machine = described_class.new
245
+ state_machine.save
246
+ state_machine.submit
247
+
248
+ described_class.awaiting_review.size.should eq(1)
249
+ described_class.reviewable.size.should eq(1)
250
+ end
251
+
202
252
  end
203
253
 
204
254
  describe ReviewCustomPersistence do
@@ -217,6 +267,21 @@ describe ReviewCustomPersistence do
217
267
 
218
268
  it_should_behave_like 'a simple state machine'
219
269
 
270
+ it "should tolerate strings as state names" do
271
+ state_machine = described_class.new
272
+ state_machine.save
273
+
274
+ state_machine.current_state.should == :new
275
+ state_machine.update_attribute(:stamp, "new")
276
+
277
+ state_machine.new?.should be_true
278
+
279
+ state_machine.submit
280
+ state_machine.initial_state.should == :new
281
+
282
+ state_machine.current_state.should == :awaiting_review
283
+ end
284
+
220
285
  end
221
286
 
222
287
  describe 'Malformed persistence definition' do
@@ -2,14 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: state_shifter 1.0.3 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "state_shifter"
8
- s.version = "0.8.1"
9
+ s.version = "1.0.3"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
11
13
  s.authors = ["Bruno Antunes"]
12
- s.date = "2012-08-28"
14
+ s.date = "2015-04-10"
13
15
  s.description = "state_shifter is a gem that adds state machine behavior to a class"
14
16
  s.email = "sardaukar.siet@gmail.com"
15
17
  s.extra_rdoc_files = [
@@ -38,55 +40,66 @@ Gem::Specification.new do |s|
38
40
  "lib/state_shifter/definition/class_methods.rb",
39
41
  "lib/state_shifter/definition/contents.rb",
40
42
  "lib/state_shifter/definition/instance_methods.rb",
43
+ "lib/state_shifter/draw.rb",
41
44
  "lib/state_shifter/event.rb",
45
+ "lib/state_shifter/railtie.rb",
42
46
  "lib/state_shifter/state.rb",
47
+ "lib/tasks/state_shifter.rake",
43
48
  "spec/spec_helper.rb",
44
49
  "spec/state_shifter_spec.rb",
45
50
  "state_shifter.gemspec"
46
51
  ]
47
52
  s.homepage = "http://github.com/sardaukar/state_shifter"
48
53
  s.licenses = ["MIT"]
49
- s.require_paths = ["lib"]
50
- s.rubygems_version = "1.8.24"
54
+ s.rubygems_version = "2.4.5"
51
55
  s.summary = "state_shifter is a gem that adds state machine behavior to a class"
52
56
 
53
57
  if s.respond_to? :specification_version then
54
- s.specification_version = 3
58
+ s.specification_version = 4
55
59
 
56
60
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
- s.add_development_dependency(%q<activerecord>, ["~> 3.2.x"])
58
- s.add_development_dependency(%q<sqlite3>, [">= 0"])
59
- s.add_development_dependency(%q<rspec-nc>, [">= 0"])
60
- s.add_development_dependency(%q<rspec>, ["~> 2.9.0"])
61
+ s.add_development_dependency(%q<activerecord>, ["~> 4.0.9"])
62
+ s.add_development_dependency(%q<sqlite3>, ["~> 1.3.10"])
63
+ s.add_development_dependency(%q<rspec>, [">= 0"])
61
64
  s.add_development_dependency(%q<yard>, ["~> 0.7"])
62
- s.add_development_dependency(%q<redcarpet>, [">= 0"])
63
- s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
64
- s.add_development_dependency(%q<bundler>, ["~> 1.1.0"])
65
+ s.add_development_dependency(%q<redcarpet>, [">= 3.2.3"])
66
+ s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
67
+ s.add_development_dependency(%q<bundler>, [">= 0"])
65
68
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
66
69
  s.add_development_dependency(%q<simplecov>, [">= 0"])
70
+ s.add_development_dependency(%q<pry>, [">= 0"])
71
+ s.add_development_dependency(%q<ruby-graphviz>, [">= 0"])
72
+ s.add_development_dependency(%q<json>, [">= 1.8.2"])
73
+ s.add_development_dependency(%q<i18n>, [">= 0.6.6"])
67
74
  else
68
- s.add_dependency(%q<activerecord>, ["~> 3.2.x"])
69
- s.add_dependency(%q<sqlite3>, [">= 0"])
70
- s.add_dependency(%q<rspec-nc>, [">= 0"])
71
- s.add_dependency(%q<rspec>, ["~> 2.9.0"])
75
+ s.add_dependency(%q<activerecord>, ["~> 4.0.9"])
76
+ s.add_dependency(%q<sqlite3>, ["~> 1.3.10"])
77
+ s.add_dependency(%q<rspec>, [">= 0"])
72
78
  s.add_dependency(%q<yard>, ["~> 0.7"])
73
- s.add_dependency(%q<redcarpet>, [">= 0"])
74
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
75
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
79
+ s.add_dependency(%q<redcarpet>, [">= 3.2.3"])
80
+ s.add_dependency(%q<rdoc>, ["~> 4.0"])
81
+ s.add_dependency(%q<bundler>, [">= 0"])
76
82
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
77
83
  s.add_dependency(%q<simplecov>, [">= 0"])
84
+ s.add_dependency(%q<pry>, [">= 0"])
85
+ s.add_dependency(%q<ruby-graphviz>, [">= 0"])
86
+ s.add_dependency(%q<json>, [">= 1.8.2"])
87
+ s.add_dependency(%q<i18n>, [">= 0.6.6"])
78
88
  end
79
89
  else
80
- s.add_dependency(%q<activerecord>, ["~> 3.2.x"])
81
- s.add_dependency(%q<sqlite3>, [">= 0"])
82
- s.add_dependency(%q<rspec-nc>, [">= 0"])
83
- s.add_dependency(%q<rspec>, ["~> 2.9.0"])
90
+ s.add_dependency(%q<activerecord>, ["~> 4.0.9"])
91
+ s.add_dependency(%q<sqlite3>, ["~> 1.3.10"])
92
+ s.add_dependency(%q<rspec>, [">= 0"])
84
93
  s.add_dependency(%q<yard>, ["~> 0.7"])
85
- s.add_dependency(%q<redcarpet>, [">= 0"])
86
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
87
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
94
+ s.add_dependency(%q<redcarpet>, [">= 3.2.3"])
95
+ s.add_dependency(%q<rdoc>, ["~> 4.0"])
96
+ s.add_dependency(%q<bundler>, [">= 0"])
88
97
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
89
98
  s.add_dependency(%q<simplecov>, [">= 0"])
99
+ s.add_dependency(%q<pry>, [">= 0"])
100
+ s.add_dependency(%q<ruby-graphviz>, [">= 0"])
101
+ s.add_dependency(%q<json>, [">= 1.8.2"])
102
+ s.add_dependency(%q<i18n>, [">= 0.6.6"])
90
103
  end
91
104
  end
92
105