yard-state_machine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use 1.9.3@yard-state_machine
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ yard-state_machine (0.0.1)
5
+ ruby-graphviz (~> 1.0.0)
6
+ yard (~> 0.7.3)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ ruby-graphviz (1.0.0)
12
+ yard (0.7.3)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ yard-state_machine!
@@ -0,0 +1 @@
1
+ require 'yard-state_machine/yard/state_machine'
@@ -0,0 +1,8 @@
1
+ module YARD
2
+ # A YARD plugin for automatically documenting state_machine gem managed state machines.
3
+ module StateMachine
4
+ end
5
+ end
6
+
7
+ require 'yard-state_machine/yard/state_machine/handlers'
8
+ require 'yard-state_machine/yard/state_machine/templates'
@@ -0,0 +1,14 @@
1
+ module YARD
2
+ module StateMachine
3
+
4
+ # YARD custom handlers for integrating the StateMachine DSL with the
5
+ # YARD documentation system
6
+ module Handlers
7
+ end
8
+
9
+ end
10
+ end
11
+
12
+ require 'yard-state_machine/yard/state_machine/handlers/state_machine_macro_handler'
13
+ require 'yard-state_machine/yard/state_machine/handlers/state_machine_event_handler'
14
+ require 'yard-state_machine/yard/state_machine/handlers/state_machine_transition_handler'
@@ -0,0 +1,56 @@
1
+ require 'yard'
2
+
3
+ module YARD
4
+ module StateMachine
5
+ module Handlers
6
+
7
+ # Handles and processes the #state_machine macro
8
+ class StateMachineEventHandler < ::YARD::Handlers::Ruby::Base
9
+
10
+ handles method_call(:event)
11
+
12
+ def process
13
+ return unless called_within_state_machine_macro?
14
+
15
+ event = extract_event_from_statement(statement)
16
+ decorate_event_with_description event
17
+
18
+ append_event_to_owner event
19
+
20
+ end
21
+
22
+ private
23
+
24
+ def called_within_state_machine_macro?
25
+ owner && owner.kind_of?(Hash) && owner.respond_to?(:[]) && owner[:type] == :state_machine_macro
26
+ end
27
+
28
+ def extract_event_from_statement statement
29
+ return {
30
+ :name => extract_event_name(statement.parameters),
31
+ :type => :state_machine_event,
32
+ :macro => owner,
33
+ :description => {
34
+ }
35
+ }
36
+ end
37
+
38
+ def extract_event_name from_statement
39
+ from_statement.jump(:ident, :tstring_content).source
40
+ end
41
+
42
+ def decorate_event_with_description event
43
+ parse_block statement.last.last, :owner => event
44
+ end
45
+
46
+ def append_event_to_owner event
47
+ owner[:description][:events] ||= Hash.new
48
+ owner[:description][:events][event[:name].to_sym] = event
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+
@@ -0,0 +1,67 @@
1
+ require 'yard'
2
+
3
+ module YARD
4
+ module StateMachine
5
+ module Handlers
6
+
7
+ # Handles and processes the #state_machine macro
8
+ class StateMachineMacroHandler < ::YARD::Handlers::Ruby::Base
9
+
10
+ handles method_call(:state_machine)
11
+ namespace_only
12
+
13
+ def process
14
+ macro = extract_macro(statement)
15
+ decorate_macro_with_description macro
16
+ append_state_machine_to_namespace macro
17
+ end
18
+
19
+ private
20
+
21
+ def extract_macro from_statement
22
+ state_machine_name_ast, state_machine_options_ast = from_statement.parameters
23
+
24
+ return {
25
+ :type => :state_machine_macro,
26
+ :name => extract_string_or_symbol_name(state_machine_name_ast),
27
+ :namespace => namespace,
28
+ :options => extract_hash_from_ast(state_machine_options_ast),
29
+ :description => {
30
+ }
31
+ }
32
+ end
33
+
34
+ def extract_string_or_symbol_name ast
35
+ raise 'symbol expected (state_machine name) as first argument to state_machine' unless ast.type == :symbol_literal
36
+
37
+ # tstring_content/ident nodes in the ruby AST represent the content of strings and symbols
38
+ ast.jump(:tstring_content, :ident).source
39
+ end
40
+
41
+ def extract_hash_from_ast ast
42
+ return nil unless ast
43
+ raise 'hash expected (state_machine macro options) as second argument to state_machine' unless ast.children.all?{|node| node.type == :assoc}
44
+
45
+ options_hash = Hash.new
46
+ ast.children.each do |assoc|
47
+ key = assoc[0].jump(:ident).source.to_sym
48
+ value = assoc[1].source
49
+ options_hash[key] = value
50
+ end
51
+ return options_hash
52
+ end
53
+
54
+ def decorate_macro_with_description for_macro
55
+ parse_block statement.last.last, :owner => for_macro
56
+ end
57
+
58
+ def append_state_machine_to_namespace macro
59
+ namespace['state_machine_state_machines'] ||= Hash.new
60
+ namespace['state_machine_state_machines'][macro[:name]] = macro
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,72 @@
1
+ require 'yard'
2
+
3
+ module YARD
4
+ module StateMachine
5
+ module Handlers
6
+
7
+ # Handles and processes the #state_machine macro
8
+ class StateMachineTransitionHandler < ::YARD::Handlers::Ruby::Base
9
+
10
+ handles method_call(:transition)
11
+
12
+ def process
13
+ return unless called_within_state_machine_event?
14
+
15
+ transition = extract_transition_from_statement(statement)
16
+
17
+ append_transition_to_owner transition
18
+ end
19
+
20
+ private
21
+
22
+ def called_within_state_machine_event?
23
+ owner && owner.kind_of?(Hash) && owner.respond_to?(:[]) && owner[:type] == :state_machine_event
24
+ end
25
+
26
+ def extract_transition_from_statement statement
27
+ transition_specifier = statement.parameters.first.jump(:assoc)
28
+
29
+ raise 'expected first argument (transitions hash) to be a hash' unless transition_specifier.type == :assoc
30
+
31
+ return {
32
+ :type => :state_machine_transition,
33
+ :event => owner,
34
+ :from_states => extract_origin_states_from_parameters(transition_specifier),
35
+ :to_state => extract_destination_states_from_parameters(transition_specifier)
36
+ }
37
+ end
38
+
39
+ def extract_origin_states_from_parameters parameters
40
+ keys = parameters[0]
41
+ origin_states = case keys.type
42
+ when :symbol_literal
43
+ [ keys.jump(:ident).source.to_sym ]
44
+ when :array
45
+ keys.first.children.map do |obj|
46
+ raise "expected array hash key to contain only symbols (type encountered was '#{obj.type}')" unless obj.type == :symbol_literal
47
+ obj.jump(:ident).source.to_sym
48
+ end
49
+ when :vcall
50
+ keys.jump(:ident).source.to_sym
51
+ else
52
+ raise "unrecognized parameter type for transition hash key (type was '#{keys.type}')"
53
+ end
54
+ end
55
+
56
+ def extract_destination_states_from_parameters parameters
57
+ values = parameters[1]
58
+ raise "unrecognized parameter type for transition hash value (type was '#{values.type}')" unless values.type == :symbol_literal
59
+ values.jump(:ident).source.to_sym
60
+ end
61
+
62
+ def append_transition_to_owner transition
63
+ owner[:description][:transitions] ||= Array.new
64
+ owner[:description][:transitions] << transition
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+
@@ -0,0 +1,4 @@
1
+ require 'yard'
2
+
3
+ state_machine_template_path = File.join(File.expand_path(File.dirname(__FILE__)), 'templates')
4
+ YARD::Templates::Engine.register_template_path state_machine_template_path
@@ -0,0 +1,58 @@
1
+ require 'graphviz'
2
+
3
+ def init
4
+ super
5
+ sections.place(:state_machine_details).before(:children)
6
+ end
7
+
8
+ def state_machine_details
9
+ @state_machines = object['state_machine_state_machines']
10
+
11
+ return unless @state_machines
12
+
13
+ @state_machine_image_objects = render_state_machine_data(@state_machines)
14
+
15
+ erb(:state_machine_details)
16
+ end
17
+
18
+
19
+ def render_state_machine_data state_machines
20
+
21
+ state_machine_image_paths = Hash.new
22
+
23
+ images_base_path = File.dirname(serializer.serialized_path(object))
24
+
25
+ state_machines.each do |state_machine_name, state_machine|
26
+
27
+ image_file_name = object.name.to_s + '_' + state_machine_name + '.png'
28
+
29
+ image_path = File.join(images_base_path, image_file_name)
30
+
31
+ content = GraphViz.new(:G, :type => :digraph) do |graph|
32
+
33
+ state_machine[:description][:events].each do |event_name, event|
34
+
35
+ event[:description][:transitions].each do |transition|
36
+
37
+ to_state = graph.add_node(transition[:to_state].to_s)
38
+
39
+ transition[:from_states].each do |state|
40
+ from_state = graph.add_node(state.to_s)
41
+ link = graph.add_edge(from_state, to_state)
42
+ link.label = event[:name].to_s
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end.output(:png => String)
50
+
51
+ serializer.serialize(image_path, content)
52
+
53
+ state_machine_image_paths[state_machine_name] = image_path
54
+ end
55
+
56
+ return state_machine_image_paths
57
+
58
+ end
@@ -0,0 +1,15 @@
1
+ <h2>State Machines</h2>
2
+
3
+ This class contains <%= @state_machines.count %> state machine<%= 's' if @state_machines.count > 1 %> managed by the state_machine gem.
4
+
5
+ <% @state_machines.each do |state_machine_name, state_machine| %>
6
+ <h3><%= h state_machine_name %></h3>
7
+ <% if state_machine[:docstring] %>
8
+ <p><%= h state_machine[:docstring] %></p>
9
+ <% end %>
10
+ <% if @state_machine_image_objects[state_machine_name] %>
11
+
12
+ <img alt="state machine diagram for state machine <%= h state_machine_name %>" src="<%= url_for(@state_machine_image_objects[state_machine_name]) %>" />
13
+
14
+ <% end %>
15
+ <% end %>
@@ -0,0 +1,15 @@
1
+ module YARD
2
+ module StateMachine
3
+
4
+ module Version
5
+ MAJOR = '0'
6
+ MINOR = '0'
7
+ PATCH = '1'
8
+
9
+ def self.to_standard_version_s
10
+ return [MAJOR, MINOR, PATCH].join('.')
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('./lib/yard-state_machine/yard/state_machine/version')
3
+
4
+ Gem::Specification.new do |gem|
5
+
6
+ gem.name = 'yard-state_machine'
7
+ gem.version = YARD::StateMachine::Version.to_standard_version_s
8
+
9
+ gem.authors = ["Justin Lynn"]
10
+ gem.email = ["justinlynn@gmail.com"]
11
+
12
+ gem.summary = %q{A YARD Plugin for state_machine integration.}
13
+ gem.description = %q{A YARD Plugin for state_machine integration. Automatically documents state_machine DSL defined state machines.}
14
+
15
+ gem.homepage = 'https://github.com/justinlynn/yard-state_machine'
16
+
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename f }
18
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split "\n"
19
+ gem.files = `git ls-files`.split "\n"
20
+
21
+ gem.require_paths = ['lib']
22
+
23
+ gem.required_ruby_version = '>= 1.9.3'
24
+ gem.required_rubygems_version = Gem::Requirement.new '>= 1.8'
25
+
26
+ gem.add_dependency 'yard', '~> 0.7.3'
27
+ gem.add_dependency 'ruby-graphviz', '~> 1.0.0'
28
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yard-state_machine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Justin Lynn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: yard
16
+ requirement: &16090340 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.7.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *16090340
25
+ - !ruby/object:Gem::Dependency
26
+ name: ruby-graphviz
27
+ requirement: &16089620 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *16089620
36
+ description: A YARD Plugin for state_machine integration. Automatically documents
37
+ state_machine DSL defined state machines.
38
+ email:
39
+ - justinlynn@gmail.com
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .rvmrc
45
+ - Gemfile
46
+ - Gemfile.lock
47
+ - lib/yard-state_machine.rb
48
+ - lib/yard-state_machine/yard/state_machine.rb
49
+ - lib/yard-state_machine/yard/state_machine/handlers.rb
50
+ - lib/yard-state_machine/yard/state_machine/handlers/state_machine_event_handler.rb
51
+ - lib/yard-state_machine/yard/state_machine/handlers/state_machine_macro_handler.rb
52
+ - lib/yard-state_machine/yard/state_machine/handlers/state_machine_transition_handler.rb
53
+ - lib/yard-state_machine/yard/state_machine/templates.rb
54
+ - lib/yard-state_machine/yard/state_machine/templates/default/class/html/setup.rb
55
+ - lib/yard-state_machine/yard/state_machine/templates/default/class/html/state_machine_details.erb
56
+ - lib/yard-state_machine/yard/state_machine/version.rb
57
+ - yard-state_machine.gemspec
58
+ homepage: https://github.com/justinlynn/yard-state_machine
59
+ licenses: []
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 1.9.3
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '1.8'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 1.8.10
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: A YARD Plugin for state_machine integration.
82
+ test_files: []
83
+ has_rdoc: