state_shifter 0.8.1 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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