umlify 1.2.1 → 1.2.4
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.
- data/bin/umlify +1 -1
- data/lib/umlify.rb +11 -1
- data/lib/umlify/parser_sexp.rb +10 -2
- data/lib/umlify/runner.rb +6 -4
- data/lib/umlify/version.rb +1 -1
- data/test/parser_sexp_test.rb +17 -2
- data/test/runner_test.rb +8 -0
- metadata +2 -5
- data/lib/umlify/parser.rb +0 -86
- data/test/parser_test.rb +0 -126
data/bin/umlify
CHANGED
data/lib/umlify.rb
CHANGED
@@ -34,8 +34,18 @@
|
|
34
34
|
|
35
35
|
require 'umlify/version'
|
36
36
|
require 'umlify/runner'
|
37
|
-
require 'umlify/parser'
|
38
37
|
require 'umlify/parser_sexp'
|
39
38
|
require 'umlify/extension'
|
40
39
|
require 'umlify/uml_class'
|
41
40
|
require 'umlify/diagram'
|
41
|
+
|
42
|
+
module Umlify
|
43
|
+
class << self
|
44
|
+
|
45
|
+
# Executes umlify with the given set of options
|
46
|
+
def execute args
|
47
|
+
Umlify::Runner.new(args).run
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/umlify/parser_sexp.rb
CHANGED
@@ -51,7 +51,14 @@ module Umlify
|
|
51
51
|
|
52
52
|
# Creates a UmlClass from a class s-expression
|
53
53
|
def parse_class class_s_exp
|
54
|
-
|
54
|
+
|
55
|
+
# Checks if the class is in a module
|
56
|
+
if class_s_exp[1].class == Symbol
|
57
|
+
uml_class = UmlClass.new class_s_exp[1].to_s
|
58
|
+
else
|
59
|
+
classname = class_s_exp[1][1][1].to_s+'::'+class_s_exp[1][2].to_s
|
60
|
+
uml_class = UmlClass.new classname
|
61
|
+
end
|
55
62
|
|
56
63
|
# Let's start by building the associations of the class
|
57
64
|
each_association_for class_s_exp do |variable, type, cardinality|
|
@@ -65,7 +72,8 @@ module Umlify
|
|
65
72
|
uml_class.parent = class_s_exp[2][1].to_s
|
66
73
|
elsif class_s_exp[2] and class_s_exp[2][0] == :colon2
|
67
74
|
# If the parent class belongs to a module
|
68
|
-
|
75
|
+
classname = class_s_exp[2][1][1].to_s+'::'+class_s_exp[2][2].to_s
|
76
|
+
uml_class.parent = classname
|
69
77
|
end
|
70
78
|
|
71
79
|
# Looks-up for instance methods
|
data/lib/umlify/runner.rb
CHANGED
@@ -7,12 +7,13 @@ module Umlify
|
|
7
7
|
# and generates and save a uml diagram using yUML API.
|
8
8
|
class Runner
|
9
9
|
|
10
|
-
attr_reader :smart_mode
|
10
|
+
attr_reader :smart_mode, :html_mode
|
11
11
|
|
12
12
|
# Takes as input an array with file names
|
13
13
|
def initialize args
|
14
14
|
@args = args
|
15
15
|
@smart_mode = false
|
16
|
+
@html_mode = false
|
16
17
|
end
|
17
18
|
|
18
19
|
# Runs the application
|
@@ -24,9 +25,9 @@ module Umlify
|
|
24
25
|
else
|
25
26
|
puts "umlifying"
|
26
27
|
|
27
|
-
@
|
28
|
+
@parser_sexp = ParserSexp.new @args
|
28
29
|
|
29
|
-
if classes = @
|
30
|
+
if classes = @parser_sexp.parse_sources!
|
30
31
|
@diagram = Diagram.new
|
31
32
|
|
32
33
|
if @smart_mode
|
@@ -42,7 +43,7 @@ module Umlify
|
|
42
43
|
image = download_image
|
43
44
|
save_to_file image
|
44
45
|
|
45
|
-
puts 'http://yuml.me'+@diagram.get_uri
|
46
|
+
puts 'http://yuml.me'+@diagram.get_uri if @debug_mode
|
46
47
|
puts "Saved in uml.png"
|
47
48
|
else
|
48
49
|
puts "No ruby files in the directory"
|
@@ -54,6 +55,7 @@ module Umlify
|
|
54
55
|
def parse_options
|
55
56
|
OptionParser.new do |opts|
|
56
57
|
opts.on("-s", "--smart") { @smart_mode = true }
|
58
|
+
opts.on("-h", "--html") { @html_mode = true }
|
57
59
|
end.parse! @args
|
58
60
|
end
|
59
61
|
|
data/lib/umlify/version.rb
CHANGED
data/test/parser_sexp_test.rb
CHANGED
@@ -128,9 +128,25 @@ class ParserSexpTest < Test::Unit::TestCase
|
|
128
128
|
END_FILE
|
129
129
|
bar = @p.parse_file(test)[0]
|
130
130
|
assert_instance_of Umlify::UmlClass, bar
|
131
|
-
assert_equal "Hash", bar.parent
|
131
|
+
assert_equal "SomeModule::Hash", bar.parent
|
132
132
|
end
|
133
133
|
|
134
|
+
should "parse classes from a module" do
|
135
|
+
test = <<-END_FILE
|
136
|
+
class SomeModule::Bar < Hash
|
137
|
+
|
138
|
+
def initialize
|
139
|
+
end
|
140
|
+
|
141
|
+
def save
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
END_FILE
|
146
|
+
bar = @p.parse_file(test)[0]
|
147
|
+
assert_instance_of Umlify::UmlClass, bar
|
148
|
+
assert_equal "SomeModule::Bar", bar.name
|
149
|
+
end
|
134
150
|
|
135
151
|
should "parse file with multiple classes" do
|
136
152
|
test = <<-END_FILE
|
@@ -148,7 +164,6 @@ class ParserSexpTest < Test::Unit::TestCase
|
|
148
164
|
should "return an array of UmlClasses when the parsing is done" do
|
149
165
|
p = Umlify::ParserSexp.new Dir[File.dirname(__FILE__)+'/fixtures/*']
|
150
166
|
parsed_classes = p.parse_sources!
|
151
|
-
puts "here : #{parsed_classes}"
|
152
167
|
assert_equal 3, parsed_classes.count
|
153
168
|
end
|
154
169
|
|
data/test/runner_test.rb
CHANGED
@@ -14,6 +14,14 @@ class RunnerTest < Test::Unit::TestCase
|
|
14
14
|
assert r.smart_mode
|
15
15
|
end
|
16
16
|
|
17
|
+
should "print the api url when passed -h or --html option" do
|
18
|
+
r = Umlify::Runner.new(["-h"])
|
19
|
+
r.run
|
20
|
+
assert r.html_mode
|
21
|
+
r = Umlify::Runner.new(["--html"])
|
22
|
+
r.run
|
23
|
+
assert r.html_mode
|
24
|
+
end
|
17
25
|
end
|
18
26
|
end
|
19
27
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: umlify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.2.
|
5
|
+
version: 1.2.4
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Michael Sokol
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-14 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -61,12 +61,10 @@ files:
|
|
61
61
|
- lib/umlify.rb
|
62
62
|
- lib/umlify/version.rb
|
63
63
|
- lib/umlify/runner.rb
|
64
|
-
- lib/umlify/parser.rb
|
65
64
|
- lib/umlify/parser_sexp.rb
|
66
65
|
- lib/umlify/extension.rb
|
67
66
|
- lib/umlify/uml_class.rb
|
68
67
|
- lib/umlify/diagram.rb
|
69
|
-
- test/parser_test.rb
|
70
68
|
- test/diagram_test.rb
|
71
69
|
- test/uml_class_test.rb
|
72
70
|
- test/runner_test.rb
|
@@ -101,7 +99,6 @@ signing_key:
|
|
101
99
|
specification_version: 3
|
102
100
|
summary: umlify is a tool that creates class diagrams from your code.
|
103
101
|
test_files:
|
104
|
-
- test/parser_test.rb
|
105
102
|
- test/uml_class_test.rb
|
106
103
|
- test/parser_sexp_test.rb
|
107
104
|
- test/diagram_test.rb
|
data/lib/umlify/parser.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
module Umlify
|
2
|
-
|
3
|
-
# First version of the ruby parser, using regular expression.
|
4
|
-
# Parser is responsible for parsing ruby source files and building an array
|
5
|
-
# of uml classes
|
6
|
-
class Parser
|
7
|
-
|
8
|
-
# An array containing all the parsed classes
|
9
|
-
# type: UmlClass
|
10
|
-
attr_accessor :classes
|
11
|
-
|
12
|
-
# files should be an array containing file names with the correct path
|
13
|
-
def initialize files
|
14
|
-
@files = files
|
15
|
-
@classes = []
|
16
|
-
end
|
17
|
-
|
18
|
-
# Parses the source code of the files in @files
|
19
|
-
# to build uml classes. Returns an array containing all the
|
20
|
-
# parsed classes or nil if no ruby file were found in the
|
21
|
-
# @files array.
|
22
|
-
def parse_sources!
|
23
|
-
|
24
|
-
@source_files = @files.select {|f| f.match /\.rb/}
|
25
|
-
return nil if @source_files.empty?
|
26
|
-
|
27
|
-
@source_files.each do |file|
|
28
|
-
puts "processing #{file}..."
|
29
|
-
f = File.open file, 'r'
|
30
|
-
(parse_file f).each {|c| @classes << c}
|
31
|
-
f.close
|
32
|
-
end
|
33
|
-
|
34
|
-
@classes
|
35
|
-
end
|
36
|
-
|
37
|
-
# Parse the given file or string, and return the parsed classes
|
38
|
-
def parse_file file
|
39
|
-
classes_in_file = []
|
40
|
-
current_class = nil
|
41
|
-
type_annotation = nil
|
42
|
-
|
43
|
-
file.each do |line|
|
44
|
-
|
45
|
-
# This parses the classes
|
46
|
-
line.match(/^\s*class ([\w]*)\b[\s]*$/) do |m|
|
47
|
-
current_class = UmlClass.new m[1]
|
48
|
-
classes_in_file << current_class
|
49
|
-
end
|
50
|
-
|
51
|
-
# This parses the classes and its parent (class Foo < Bar)
|
52
|
-
line.match(/^\s*class ([\w]*) < ([\w]*)\b/) do |m|
|
53
|
-
current_class = UmlClass.new m[1]
|
54
|
-
current_class.parent = m[2]
|
55
|
-
classes_in_file << current_class
|
56
|
-
end
|
57
|
-
|
58
|
-
if current_class
|
59
|
-
|
60
|
-
# This parses the @variables
|
61
|
-
line.match(/@([\w]*)\b/) do |m|
|
62
|
-
current_class.variables << m[1] unless current_class.variables.include? m[1]
|
63
|
-
end
|
64
|
-
|
65
|
-
# This parses the methods
|
66
|
-
line.match(/def ([\w]*)\b/) do |m|
|
67
|
-
current_class.methods << m[1] unless current_class.methods.include? m[1]
|
68
|
-
end
|
69
|
-
|
70
|
-
# This raises the type_annotation flag
|
71
|
-
line.match(/# type: ([\w]*)\b/) {|m| type_annotation = m[1]}
|
72
|
-
|
73
|
-
# This adds an association to the current class, using the type_annotation
|
74
|
-
# if type_annotation has been set
|
75
|
-
line.match(/(attr_accessor|attr_reader|attr_writer) :([\w]*)\b/) do |m|
|
76
|
-
current_class.associations[m[2]] = type_annotation
|
77
|
-
type_annotation = nil
|
78
|
-
end if type_annotation
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
classes_in_file
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/test/parser_test.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
require 'shoulda'
|
2
|
-
require 'umlify'
|
3
|
-
|
4
|
-
class ParserTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
context "Parser" do
|
7
|
-
|
8
|
-
setup do
|
9
|
-
fixture = ["somefile.rb", "someotherfile.rb"]
|
10
|
-
@p = Umlify::Parser.new fixture
|
11
|
-
end
|
12
|
-
|
13
|
-
should "respond to parse_sources!" do
|
14
|
-
assert_respond_to @p, :parse_sources!
|
15
|
-
end
|
16
|
-
|
17
|
-
should "return nil if no source file in the given directory" do
|
18
|
-
parser = Umlify::Parser.new ["not_source", "still_not_source"]
|
19
|
-
assert_equal nil, parser.parse_sources!
|
20
|
-
end
|
21
|
-
|
22
|
-
should "parse class names" do
|
23
|
-
test = <<-END_FILE
|
24
|
-
class AClassName
|
25
|
-
end
|
26
|
-
END_FILE
|
27
|
-
assert_equal 'AClassName', @p.parse_file(test)[0].name
|
28
|
-
end
|
29
|
-
|
30
|
-
should "parse class name of inherited classes" do
|
31
|
-
test = <<-END_FILE
|
32
|
-
class AClassName < SuperClass
|
33
|
-
end
|
34
|
-
END_FILE
|
35
|
-
assert_equal 'AClassName', @p.parse_file(test)[0].name
|
36
|
-
end
|
37
|
-
|
38
|
-
should "parse @variables in classes" do
|
39
|
-
test = <<-END_FILE
|
40
|
-
class Bar
|
41
|
-
def foo
|
42
|
-
@a_variable = "foo"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
END_FILE
|
46
|
-
bar = @p.parse_file(test)[0]
|
47
|
-
assert_instance_of Umlify::UmlClass, bar
|
48
|
-
assert bar.variables.include? "a_variable"
|
49
|
-
end
|
50
|
-
|
51
|
-
should "parse attr_accessor when preceeded by a # type: Type annotation" do
|
52
|
-
test = <<-END_FILE
|
53
|
-
class Bar
|
54
|
-
|
55
|
-
# type: FooBar
|
56
|
-
attr_accessor :unicorn
|
57
|
-
|
58
|
-
def foo
|
59
|
-
end
|
60
|
-
end
|
61
|
-
END_FILE
|
62
|
-
bar = @p.parse_file(test)[0]
|
63
|
-
assert_instance_of Umlify::UmlClass, bar
|
64
|
-
assert_equal "FooBar", bar.associations['unicorn']
|
65
|
-
end
|
66
|
-
|
67
|
-
should "parse attr_reader when preceeded by a # type: Type annotation" do
|
68
|
-
test = <<-END_FILE
|
69
|
-
class Bar
|
70
|
-
|
71
|
-
# type: FooBar
|
72
|
-
attr_reader :unicorn
|
73
|
-
|
74
|
-
def foo
|
75
|
-
end
|
76
|
-
end
|
77
|
-
END_FILE
|
78
|
-
bar = @p.parse_file(test)[0]
|
79
|
-
assert_instance_of Umlify::UmlClass, bar
|
80
|
-
assert_equal "FooBar", bar.associations['unicorn']
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
should "parse attr_writer when preceeded by a # type: Type annotation" do
|
85
|
-
test = <<-END_FILE
|
86
|
-
class Bar
|
87
|
-
|
88
|
-
# type: FooBar
|
89
|
-
attr_writer :unicorn
|
90
|
-
|
91
|
-
def foo
|
92
|
-
end
|
93
|
-
end
|
94
|
-
END_FILE
|
95
|
-
bar = @p.parse_file(test)[0]
|
96
|
-
assert_instance_of Umlify::UmlClass, bar
|
97
|
-
assert_equal "FooBar", bar.associations['unicorn']
|
98
|
-
end
|
99
|
-
|
100
|
-
should "parse inherited classes" do
|
101
|
-
test = <<-END_FILE
|
102
|
-
class Bar < Hash
|
103
|
-
|
104
|
-
def initialize
|
105
|
-
end
|
106
|
-
|
107
|
-
def save
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
112
|
-
END_FILE
|
113
|
-
bar = @p.parse_file(test)[0]
|
114
|
-
assert_instance_of Umlify::UmlClass, bar
|
115
|
-
assert_equal "Hash", bar.parent
|
116
|
-
end
|
117
|
-
|
118
|
-
should "return an array of UmlClasses when the parsing is done" do
|
119
|
-
p = Umlify::Parser.new Dir[File.dirname(__FILE__)+'/fixtures/*']
|
120
|
-
parsed_classes = p.parse_sources!
|
121
|
-
puts "here : #{parsed_classes}"
|
122
|
-
assert_equal 3, parsed_classes.count
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
end
|