umlify 0.3.3 → 0.6.1

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/README.md ADDED
@@ -0,0 +1,114 @@
1
+ _ _ __
2
+ | (_)/ _|
3
+ _ _ _ __ ___ | |_| |_ _ _
4
+ | | | | '_ ` _ \| | | _| | | |
5
+ | |_| | | | | | | | | | | |_| |
6
+ \__,_|_| |_| |_|_|_|_| \__, |
7
+ __/ |
8
+ |___/
9
+
10
+ umlify is a tool that creates
11
+ uml class diagrams from your code
12
+
13
+ <https://github.com/mikaa123/umlify>
14
+
15
+ Introduction
16
+ ------------
17
+
18
+ umlify takes your ruby project's source code and creates an uml class diagram out of it.
19
+
20
+ Installation
21
+ ------------
22
+
23
+ gem install umlify
24
+
25
+ How to use
26
+ ----------
27
+
28
+ 1. Go to your gem project directory
29
+ 2. type: `umlify lib/*/*`
30
+ 3. Open uml.html
31
+
32
+ Example
33
+ -------
34
+
35
+ Here is umlify umlified:
36
+
37
+ ![umlify's uml](http://img43.imageshack.us/img43/2756/umlify.png)
38
+
39
+ Features
40
+ --------
41
+
42
+ * __new__ now supports inhertiance (v0.4.2)
43
+ * supports associations (see "How to add associations to a diagram)
44
+ * supports methods and instance variables
45
+
46
+ How it works
47
+ ------------
48
+
49
+ umlify parses your source codes using regular expressions to build an uml
50
+ diagram using [yUML](http://yuml.me/)'s api.
51
+
52
+ Note: Regexps parsing is really dirty. This point needs serious
53
+ improvement
54
+
55
+ On dynamic languages
56
+ --------------------
57
+
58
+ Ruby's extreme decoupling and duck-typing philosophy doesn't judge a class by its hierarchy.
59
+ Thus, variables don't have a predefined type, which conflicts with uml's static typed object-model.
60
+ The objective of this project isn't to bend uml's model to make it semantically comply with
61
+ duck typing (by the use of interfaces, or other tricks), but to add a basic visual representation
62
+ of the code of your project for documenting and helping maintainers.
63
+
64
+ How to add associations to a diagram
65
+ ------------------------------------
66
+
67
+ Because of the above point, there's no direct way to automatically draw associations between your
68
+ classes. However, if you want an association to be shown on your diagram simply add an annotation
69
+ on top of an `attr_accessor`, such as:
70
+
71
+ # type: Unicorn
72
+ attr_accessor :animal
73
+
74
+ Contribute
75
+ ----------
76
+
77
+ If you are interested by this project (I hope you are!), you can send me your comments
78
+ (mikaa123 at gmail), test the application and create some issue when you find a bug.
79
+
80
+ If you want to contribute, you can check the TODO, it's a good place to start. :)
81
+ Just fork and send a pull request. I'd love to have some help.
82
+
83
+ Not having the expected results?
84
+ --------------------------------
85
+
86
+ If you have found a bug, or if the results you obtained don't correspond
87
+ to your code, you can raise an issue and link to your github project
88
+ page.
89
+
90
+ Real project testing is way more efficient than on test cases. :)
91
+
92
+ License
93
+ -------
94
+
95
+ Copyright (C) 2011 Michael Sokol
96
+
97
+ Permission is hereby granted, free of charge, to any person obtaining a copy
98
+ of this software and associated documentation files (the "Software"), to deal
99
+ in the Software without restriction, including without limitation the rights
100
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
101
+ copies of the Software, and to permit persons to whom the Software is
102
+ furnished to do so, subject to the following conditions:
103
+
104
+ The above copyright notice and this permission notice shall be included in
105
+ all copies or substantial portions of the Software.
106
+
107
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
108
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
109
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
110
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
111
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
112
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
113
+ THE SOFTWARE.
114
+
@@ -17,17 +17,20 @@ module Umlify
17
17
  end
18
18
 
19
19
  # Adds the given statement to the @diagram array
20
+ # Statement can either be a String or an UmlClass
20
21
  def add statement
21
22
  # TODO: Add some sort of validation
22
23
 
23
24
  @statements << statement if statement.is_a? String
24
25
  if statement.is_a? UmlClass
25
26
 
26
- if statement.associations.empty?
27
- @statements << statement.to_s
28
- else
29
- @statements << statement.to_s
27
+ @statements << statement.to_s
30
28
 
29
+ if statement.parent
30
+ @statements << "[#{statement.parent}]^[#{statement.name}]"
31
+ end
32
+
33
+ unless statement.associations.empty?
31
34
  statement.associations.each do |name, type|
32
35
  @statements << "[#{statement.name}]-#{name}>[#{type}]"
33
36
  end
@@ -36,9 +39,9 @@ module Umlify
36
39
  end
37
40
  end
38
41
 
39
- # Dumps the html of the diagram
40
- def export
41
- '<img src="http://yuml.me/diagram/class/'+@statements.join(", ")+'" />'
42
+ # Returns the yuml.me uri
43
+ def get_uri
44
+ uri = '/diagram/class/'+@statements.join(", ")
42
45
  end
43
46
  end
44
47
  end
data/lib/umlify/parser.rb CHANGED
@@ -26,6 +26,7 @@ module Umlify
26
26
  return nil if @source_files.empty?
27
27
 
28
28
  @source_files.each do |file|
29
+ puts "processing #{file}..."
29
30
  f = File.open file, 'r'
30
31
  (parse_file f).each {|c| @classes << c}
31
32
  f.close
@@ -43,11 +44,18 @@ module Umlify
43
44
  file.each do |line|
44
45
 
45
46
  # This parses the classes
46
- line.match(/^\s*class ([\w]*)\b/) do |m|
47
+ line.match(/^\s*class ([\w]*)\b[\s]*$/) do |m|
47
48
  current_class = UmlClass.new m[1]
48
49
  classes_in_file << current_class
49
50
  end
50
51
 
52
+ # This parses the classes and its parent (class Foo < Bar)
53
+ line.match(/^\s*class ([\w]*) < ([\w]*)\b/) do |m|
54
+ current_class = UmlClass.new m[1]
55
+ current_class.parent = m[2]
56
+ classes_in_file << current_class
57
+ end
58
+
51
59
  if current_class
52
60
 
53
61
  # This parses the @variables
@@ -65,8 +73,8 @@ module Umlify
65
73
 
66
74
  # This adds an association to the current class, using the type_annotation
67
75
  # if type_annotation has been set
68
- line.match(/attr_accessor :([\w]*)\b/) do |m|
69
- current_class.associations[m[1]] = type_annotation
76
+ line.match(/(attr_accessor|attr_reader|attr_writer) :([\w]*)\b/) do |m|
77
+ current_class.associations[m[2]] = type_annotation
70
78
  type_annotation = nil
71
79
  end if type_annotation
72
80
 
data/lib/umlify/runner.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'optparse'
2
+ require 'net/http'
2
3
 
3
4
  module Umlify
4
5
 
@@ -28,7 +29,7 @@ module Umlify
28
29
  if @args[0][0] == '-'
29
30
 
30
31
  OptionParser.new do |opts|
31
- opts.banner = "Usage: umlify [option]"
32
+ opts.banner = "Usage: umlify [option] [source-files directory]"
32
33
  opts.on("-h", "--help", "Shows this") do
33
34
  puts opts
34
35
  end
@@ -36,37 +37,33 @@ module Umlify
36
37
 
37
38
  else
38
39
  puts "umlifying"
39
- if files = get_files_from_dir(@args[0])
40
- puts "about to parse..."
41
- @parser = Parser.new files
42
40
 
43
- if classes = @parser.parse_sources!
44
- @diagram = Diagram.new
41
+ @parser = Parser.new @args
45
42
 
46
- @diagram.create do
47
- classes.each {|c| add c}
48
- end
43
+ if classes = @parser.parse_sources!
44
+ @diagram = Diagram.new
49
45
 
50
- File.open("uml.html", 'w') do |file|
51
- file << @diagram.export
52
- end
46
+ @diagram.create do
47
+ classes.each {|c| add c}
48
+ end
49
+
50
+ puts "Downloading the image from yUML, it shouldn't be long."
53
51
 
54
- puts "Saved in uml.html"
55
- else
56
- puts "No ruby files in the directory"
52
+ image = Net::HTTP.start("yuml.me", 80) do |http|
53
+ http.get(URI.escape(@diagram.get_uri))
57
54
  end
58
55
 
56
+ File.open('uml.png', 'wb') do |file|
57
+ file << image.body
58
+ end if image
59
+
60
+ puts "Saved in uml.png"
59
61
  else
60
- puts "empty directory"
62
+ puts "No ruby files in the directory"
61
63
  end
62
- end
63
64
 
64
- end
65
-
66
- private
65
+ end
67
66
 
68
- def get_files_from_dir directory
69
- Dir[directory] unless Dir[directory].empty?
70
67
  end
71
68
  end
72
69
  end
@@ -4,7 +4,7 @@ module Umlify
4
4
  # Represent a parsed uml class
5
5
  #
6
6
  class UmlClass
7
- attr_accessor :name, :variables, :methods, :associations
7
+ attr_accessor :name, :variables, :methods, :associations, :parent
8
8
 
9
9
  def initialize name
10
10
  @name = name
@@ -1,3 +1,3 @@
1
1
  module Umlify
2
- VERSION = "0.3.3"
2
+ VERSION = "0.6.1"
3
3
  end
data/lib/umlify.rb CHANGED
@@ -1,3 +1,35 @@
1
+ # _ _ __
2
+ # | (_)/ _|
3
+ # _ _ _ __ ___ | |_| |_ _ _
4
+ # | | | | '_ ` _ \| | | _| | | |
5
+ # | |_| | | | | | | | | | | |_| |
6
+ # \__,_|_| |_| |_|_|_|_| \__, |
7
+ # __/ |
8
+ # |___/
9
+ #
10
+ #
11
+ # umlify is tool that generates uml from your ruby source files. It
12
+ # works using yUML.me web api.
13
+ #
14
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ # of this software and associated documentation files (the "Software"), to deal
16
+ # in the Software without restriction, including without limitation the rights
17
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ # copies of the Software, and to permit persons to whom the Software is
19
+ # furnished to do so, subject to the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be included in
22
+ # all copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30
+ # THE SOFTWARE.
31
+
32
+
1
33
  require 'umlify/version'
2
34
  require 'umlify/runner'
3
35
  require 'umlify/parser'
data/test/diagram_test.rb CHANGED
@@ -50,17 +50,31 @@ class DiagramTest < Test::Unit::TestCase
50
50
  assert @diagram.statements.include? '[Unicorn]-chunky>[Bacon]'
51
51
  end
52
52
 
53
- should "export th yUML html" do
53
+ should "add UmlClass with parent to diagrams" do
54
54
  test_uml_class = Umlify::UmlClass.new 'Unicorn'
55
55
  test_uml_class.variables << 'foo_variable'
56
56
  test_uml_class.methods << 'bar_method'
57
+ test_uml_class.parent = "Foo"
57
58
 
58
59
  @diagram.create do
59
60
  add test_uml_class
60
61
  end
61
62
 
62
- assert_equal '<img src="http://yuml.me/diagram/class/[Unicorn|foo_variable|bar_method]" />',
63
- @diagram.export
63
+ assert @diagram.statements.include? '[Unicorn|foo_variable|bar_method]'
64
+ assert @diagram.statements.include? '[Foo]^[Unicorn]'
65
+ end
66
+
67
+ should "get the yuml uri" do
68
+ test_uml_class = Umlify::UmlClass.new 'Unicorn'
69
+ test_uml_class.variables << 'foo_variable'
70
+ test_uml_class.methods << 'bar_method'
71
+
72
+ @diagram.create do
73
+ add test_uml_class
74
+ end
75
+
76
+ assert_equal '/diagram/class/[Unicorn|foo_variable|bar_method]',
77
+ @diagram.get_uri
64
78
  end
65
79
 
66
80
  end
data/test/parser_test.rb CHANGED
@@ -27,6 +27,14 @@ class ParserTest < Test::Unit::TestCase
27
27
  assert_equal 'AClassName', @p.parse_file(test)[0].name
28
28
  end
29
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
+
30
38
  should "parse @variables in classes" do
31
39
  test = <<-END_FILE
32
40
  class Bar
@@ -56,6 +64,57 @@ class ParserTest < Test::Unit::TestCase
56
64
  assert_equal "FooBar", bar.associations['unicorn']
57
65
  end
58
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
+
59
118
  should "return an array of UmlClasses when the parsing is done" do
60
119
  p = Umlify::Parser.new Dir[File.dirname(__FILE__)+'/fixtures/*']
61
120
  parsed_classes = p.parse_sources!
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: umlify
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.3
5
+ version: 0.6.1
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-02 00:00:00 -05:00
13
+ date: 2011-03-04 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -24,7 +24,7 @@ extra_rdoc_files: []
24
24
 
25
25
  files:
26
26
  - Rakefile
27
- - README
27
+ - README.md
28
28
  - bin/umlify
29
29
  - lib/umlify.rb
30
30
  - lib/umlify/version.rb
data/README DELETED
@@ -1,19 +0,0 @@
1
- _ _ __
2
- | (_)/ _|
3
- _ _ _ __ ___ | |_| |_ _ _
4
- | | | | '_ ` _ \| | | _| | | |
5
- | |_| | | | | | | | | | | |_| |
6
- \__,_|_| |_| |_|_|_|_| \__, |
7
- __/ |
8
- |___/
9
-
10
- umlify is a tool that creates
11
- uml class diagrams from your code
12
-
13
- <https://github.com/mikaa123/umlify>
14
-
15
-
16
- Introduction
17
- ------------
18
-
19
- umlify takes your project's source code and creates an uml class diagram out of it.