uml_architect 0.0.2
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +22 -0
- data/Rakefile +1 -0
- data/architect.gemspec +29 -0
- data/bin/architect +14 -0
- data/examples/aggregation.yuml +1 -0
- data/examples/cardinality.yuml +1 -0
- data/examples/class.yuml +1 -0
- data/examples/class_with_details.yuml +1 -0
- data/examples/color_and_utf8.yuml +1 -0
- data/examples/composition.yuml +1 -0
- data/examples/dependancies.yuml +1 -0
- data/examples/directional_association.yuml +1 -0
- data/examples/inheritance.yuml +0 -0
- data/examples/interface.yuml +1 -0
- data/examples/interface_inheritance.yuml +1 -0
- data/examples/international_characters.yuml +1 -0
- data/examples/notes.yuml +1 -0
- data/examples/simple_association.yuml +1 -0
- data/examples/something_meaty.yuml +1 -0
- data/lib/architect.rb +5 -0
- data/lib/architect/association.rb +55 -0
- data/lib/architect/class.rb +30 -0
- data/lib/architect/diagram.rb +23 -0
- data/lib/architect/edge.rb +19 -0
- data/lib/architect/node.rb +19 -0
- data/lib/architect/parser.rb +53 -0
- data/lib/architect/runner.rb +20 -0
- data/lib/architect/version.rb +3 -0
- data/spec/lib/association_spec.rb +30 -0
- data/spec/lib/class_spec.rb +17 -0
- data/spec/lib/diagram_spec.rb +26 -0
- data/spec/lib/edge_spec.rb +11 -0
- data/spec/lib/node_spec.rb +19 -0
- data/spec/lib/parser_spec.rb +31 -0
- data/spec/lib/runner_spec.rb +19 -0
- data/spec/spec_helper.rb +20 -0
- metadata +192 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5e3e99db12409ac2ec2f6368b6840caff915de1d
|
4
|
+
data.tar.gz: d36b07f16eaca893037cc8d9eaf8828b8cf22810
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 536c4249dacecd20bf502b79e91e916c7727eed00c346eed208d4f704d57b6e56dafcde93824f7d0bf172d94a25e675fd2e871ce428a99a60bbea3a3f1a4274a
|
7
|
+
data.tar.gz: 51382b513dd71f722c7ed95baf6a58cc9138f9ffec02b18376a368bb736db5c60e8b693539c1553ed2cc462d33b346a77d6e081270811f493c93cb7d46ca61be
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
|
17
|
+
# Capybara features specs
|
18
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
+
|
20
|
+
# Turnip features and steps
|
21
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
23
|
+
end
|
24
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ibrahim Muhammad
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Architect
|
2
|
+
|
3
|
+
Create UML Class diagrams using a [yUML](http://yuml.me/diagram/scruffy/class/samples)-like notation.
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
$ gem install uml_architect
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
$ architect file
|
13
|
+
|
14
|
+
For what should be in the input file check out yUML samples above.
|
15
|
+
|
16
|
+
## Contributing
|
17
|
+
|
18
|
+
1. Fork it
|
19
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
20
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
21
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
22
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/architect.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'architect/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "uml_architect"
|
8
|
+
spec.version = Architect::VERSION
|
9
|
+
spec.authors = ["Ibrahim Muhammad"]
|
10
|
+
spec.email = ["ibrahim.mohammad@gmail.com"]
|
11
|
+
spec.description = %q{Create UML Class Diagrams using text}
|
12
|
+
spec.summary = %q{Create UML Class Diagrams using a simple yUML like notation}
|
13
|
+
spec.homepage = "https://github.com/whistler/architect"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = ['architect']
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "ruby-graphviz"
|
22
|
+
spec.add_dependency "listen", "2.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency 'rspec', "2.10.0"
|
27
|
+
spec.add_development_dependency 'rspec-mocks'
|
28
|
+
spec.add_development_dependency 'guard-rspec'
|
29
|
+
end
|
data/bin/architect
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << "./lib"
|
3
|
+
require 'architect/runner'
|
4
|
+
|
5
|
+
if ARGV.count != 1
|
6
|
+
puts "usage: architect file"
|
7
|
+
else
|
8
|
+
file = ARGV[0]
|
9
|
+
if File.exists?(file)
|
10
|
+
Architect::Runner.new(file, 'png')
|
11
|
+
else
|
12
|
+
puts file + " does not exist"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
[Company]<>-1>[Location], [Location]+->[Point]
|
@@ -0,0 +1 @@
|
|
1
|
+
[Customer]1-0..*[Address]
|
data/examples/class.yuml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
[User]
|
@@ -0,0 +1 @@
|
|
1
|
+
[User|+Forename+;Surname;+HashedPassword;-Salt|+Login();+Logout()]
|
@@ -0,0 +1 @@
|
|
1
|
+
[❝Customer❞{bg:orange}]❶- ☂>[Order{bg:green}]
|
@@ -0,0 +1 @@
|
|
1
|
+
[Company]++-1>[Location]
|
@@ -0,0 +1 @@
|
|
1
|
+
[HttpContext]uses -.->[Response]
|
@@ -0,0 +1 @@
|
|
1
|
+
[Order]-billing >[Address], [Order]-shipping >[Address]
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
[<<IDisposable>>;Session]
|
@@ -0,0 +1 @@
|
|
1
|
+
[<<ITask>>]^-.-[NightlyBillingTask]
|
@@ -0,0 +1 @@
|
|
1
|
+
[日本語]->[Köttbullar]
|
data/examples/notes.yuml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
[Customer]<>1->*[Order], [Customer]-[note: Aggregate Root{bg:cornsilk}]
|
@@ -0,0 +1 @@
|
|
1
|
+
[Customer]->[Billing Address]
|
@@ -0,0 +1 @@
|
|
1
|
+
[note: You can stick notes on diagrams too!{bg:cornsilk}],[Customer]<>1-orders 0..*>[Order], [Order]++*-*>[LineItem], [Order]-1>[DeliveryMethod], [Order]*-*>[Product], [Category]<->[Product], [DeliveryMethod]^[National], [DeliveryMethod]^[International]
|
data/lib/architect.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'graphviz'
|
2
|
+
require_relative 'edge'
|
3
|
+
|
4
|
+
module Architect
|
5
|
+
|
6
|
+
class Association < Edge
|
7
|
+
|
8
|
+
attr_accessor :attributes, :graph
|
9
|
+
|
10
|
+
TYPES = {
|
11
|
+
"<>" => "odiamond",
|
12
|
+
"+" => "odiamond",
|
13
|
+
"++" => "diamond",
|
14
|
+
"" => "none",
|
15
|
+
">" => "vee"
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(node1, node2, markup="->")
|
19
|
+
super node1, node2
|
20
|
+
@attributes = parse_markup(markup)
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_markup(markup)
|
24
|
+
matches = /(.*)-(.*)/.match(markup)
|
25
|
+
left = matches[1]
|
26
|
+
right = matches[2]
|
27
|
+
{arrowhead: get_arrow(right), arrowtail: get_arrow(left),
|
28
|
+
headlabel: strip_arrow(right), taillabel: strip_arrow(left),
|
29
|
+
dir: "both"}
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_arrow(string)
|
33
|
+
tokens = /([<>+]+)/.match(string)
|
34
|
+
if tokens == nil
|
35
|
+
return "none"
|
36
|
+
else
|
37
|
+
return TYPES[tokens[0]]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def strip_arrow(string)
|
42
|
+
return "" if string == nil
|
43
|
+
TYPES.keys.each do |arrow|
|
44
|
+
string = string.gsub(arrow, "")
|
45
|
+
end
|
46
|
+
return string
|
47
|
+
end
|
48
|
+
|
49
|
+
def graph(g)
|
50
|
+
g.add_edges(@node1.graphnode, @node2.graphnode, @attributes)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'node'
|
2
|
+
|
3
|
+
module Architect
|
4
|
+
|
5
|
+
class Class < Architect::Node
|
6
|
+
|
7
|
+
attr_accessor :graphnode, :markup
|
8
|
+
|
9
|
+
def initialize(markup)
|
10
|
+
if markup.index("|").nil?
|
11
|
+
@name = markup
|
12
|
+
else
|
13
|
+
tokens = /^(?<name>.+?)\|/.match(markup)
|
14
|
+
@name = tokens[:name]
|
15
|
+
end
|
16
|
+
@markup = format(markup)
|
17
|
+
@style = {shape: "record"}
|
18
|
+
end
|
19
|
+
|
20
|
+
def format(markup)
|
21
|
+
return "{" + markup.gsub(";", "\\n") + "}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def graph(g)
|
25
|
+
@graphnode = g.add_nodes(@markup, @style)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'graphviz'
|
2
|
+
require_relative 'parser'
|
3
|
+
|
4
|
+
module Architect
|
5
|
+
##
|
6
|
+
# Diagram is the base class for generating any diagram.
|
7
|
+
class Diagram
|
8
|
+
# Draw
|
9
|
+
# [diagram] string containing the markup of the diagram
|
10
|
+
def draw(diagram, output = "class_diagram.png", ext = 'png')
|
11
|
+
parser = Parser.new
|
12
|
+
elements = parser.parse(diagram)
|
13
|
+
graph = GraphViz.new("ClassDiagram", type: "digraph")
|
14
|
+
graph.node["fillcolor"] = "gray95"
|
15
|
+
graph.node["style"] = "filled"
|
16
|
+
elements.each do |element|
|
17
|
+
element.graph(graph)
|
18
|
+
end
|
19
|
+
graph.output(ext.to_sym => output)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'node'
|
2
|
+
|
3
|
+
module Architect
|
4
|
+
|
5
|
+
###
|
6
|
+
# This is a generic edge in a graph which connects two nodes
|
7
|
+
class Edge
|
8
|
+
attr_accessor :from, :to
|
9
|
+
|
10
|
+
def initialize(node1, node2)
|
11
|
+
raise node1.to_s + " must be a Node" unless node1.kind_of? Node
|
12
|
+
raise node2.to_s + " must be a Node" unless node2.kind_of? Node
|
13
|
+
@node1 = node1
|
14
|
+
@node2 = node2
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'class'
|
2
|
+
require_relative 'association'
|
3
|
+
|
4
|
+
module Architect
|
5
|
+
##
|
6
|
+
# Parses yUML files
|
7
|
+
class Parser
|
8
|
+
|
9
|
+
# [diagram] String containing yUML markup
|
10
|
+
# Returns list of classes and list of associations in diagram
|
11
|
+
def parse(diagram)
|
12
|
+
elements = []
|
13
|
+
statements = get_statements(diagram)
|
14
|
+
statements.each do |statement|
|
15
|
+
new_elements = parse_statement(statement)
|
16
|
+
elements = elements + new_elements
|
17
|
+
end
|
18
|
+
return elements
|
19
|
+
end
|
20
|
+
|
21
|
+
# [diagram] String containing yUML markup
|
22
|
+
# Returns list of statments in diagram markup
|
23
|
+
def get_statements(diagram)
|
24
|
+
statements = diagram.split(/\][,\s]*\[/) # split on "]*["
|
25
|
+
|
26
|
+
#insert removed square brackets back
|
27
|
+
statements = statements.each_with_index.map do |statement, i|
|
28
|
+
statement = statement.strip
|
29
|
+
statement = "[" + statement if statement[0] != "["
|
30
|
+
statement = statement + "]" if statement[-1] != "]"
|
31
|
+
statement
|
32
|
+
end
|
33
|
+
return statements
|
34
|
+
end
|
35
|
+
|
36
|
+
# [statement] String containing statement
|
37
|
+
# Returns a list of classes markup and association markup in the statement
|
38
|
+
def parse_statement(statement)
|
39
|
+
pattern = /\[(?<class1>.+?)\](?<association>.+?)\[(?<class2>.+)\]/
|
40
|
+
tokens = pattern.match(statement)
|
41
|
+
if tokens
|
42
|
+
class1 = Class.new(tokens[:class1])
|
43
|
+
class2 = Class.new(tokens[:class2])
|
44
|
+
association = Association.new(class1, class2, tokens[:association])
|
45
|
+
return [class1, class2, association]
|
46
|
+
else
|
47
|
+
tokens = /\[(?<class1>.*)\]/.match(statement)
|
48
|
+
class1 = Class.new(tokens[:class1])
|
49
|
+
return [class1]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'architect/diagram'
|
2
|
+
|
3
|
+
module Architect
|
4
|
+
|
5
|
+
class Runner
|
6
|
+
|
7
|
+
def initialize(file, ext)
|
8
|
+
@drawer = Architect::Diagram.new()
|
9
|
+
diagram = Kernel.open(file).read()
|
10
|
+
output_file = change_extension(file, ext)
|
11
|
+
@drawer.draw(diagram, output_file)
|
12
|
+
end
|
13
|
+
|
14
|
+
def change_extension(file, new_ext)
|
15
|
+
ext = File.extname(file).gsub(".","")
|
16
|
+
return file.gsub(ext, new_ext)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'association'
|
3
|
+
require 'class'
|
4
|
+
|
5
|
+
describe Architect::Association do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@node = Architect::Class.new("[User]")
|
9
|
+
@association = Architect::Association.new(@node, @node, "-")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "parses simple association" do
|
13
|
+
@association.attributes[:arrowhead].should == "none"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "parses association markup" do
|
17
|
+
dot = {arrowhead: "vee", arrowtail: "odiamond",
|
18
|
+
headlabel: "n", taillabel: "1", dir: "both"}
|
19
|
+
@association.parse_markup("<>1-n>").should == dot
|
20
|
+
end
|
21
|
+
|
22
|
+
it "gets arrow from string" do
|
23
|
+
@association.get_arrow("<>1").should == "odiamond"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "strips arrows from strings" do
|
27
|
+
@association.strip_arrow(">1").should == "1"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'class'
|
3
|
+
|
4
|
+
describe Architect::Class do
|
5
|
+
|
6
|
+
it "should parse class name from markup" do
|
7
|
+
class_ = Architect::Class.new("User")
|
8
|
+
class_.name.should == "User"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should parse attributes and methods" do
|
12
|
+
class_ = Architect::Class.new("User|+Firstname;+Lastname;+HashedPassword;-Salt|Login();Logout()")
|
13
|
+
class_.name.should == "User"
|
14
|
+
class_.markup.should == "{User|+Firstname\\n+Lastname\\n+HashedPassword\\n-Salt|Login()\\nLogout()}"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'diagram'
|
3
|
+
|
4
|
+
describe Architect::Diagram do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@diagram = Architect::Diagram.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can draw a class" do
|
11
|
+
@diagram.send("draw", "[User]", "class.png")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can draw an association" do
|
15
|
+
@diagram.send("draw", "[User]-[Pet]", "association.png")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can draw a class with attributes and methods" do
|
19
|
+
@diagram.send("draw", "[User|name; age; height|login(); logout()]-[Pet]", "record.png")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can draw a diagram with composition" do
|
23
|
+
@diagram.send("draw", "[Pond]<>0..1-0..*[Duck]", "composition.png")
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'node'
|
3
|
+
|
4
|
+
describe Architect::Node do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@node = Architect::Node.new("node1")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have a name" do
|
11
|
+
@node.name.should_not be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be equal to a node of the same name" do
|
15
|
+
node = Architect::Node.new("node1")
|
16
|
+
node.should == node
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parser'
|
3
|
+
|
4
|
+
describe Architect::Parser do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@parser = Architect::Parser.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can extract statements from markup" do
|
11
|
+
test = <<-EOF
|
12
|
+
[Company]<>-1>[Location],
|
13
|
+
[Location]+->[Point][Customer]1-0..*[Address]
|
14
|
+
[User][User|+Forename+;Surname;+HashedPassword;-Salt|+Login();+Logout()]
|
15
|
+
EOF
|
16
|
+
@parser.get_statements(test).count.should == 5
|
17
|
+
end
|
18
|
+
|
19
|
+
it "can extract a single class markup from statement" do
|
20
|
+
classes = @parser.parse_statement("[User]")
|
21
|
+
classes.size.should == 1
|
22
|
+
classes[0].name == "User"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can extract two class and a relationship" do
|
26
|
+
elements = @parser.parse_statement("[User]-[Cat]")
|
27
|
+
elements.size.should == 3
|
28
|
+
elements[0].name == "User"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'runner'
|
3
|
+
require 'diagram'
|
4
|
+
|
5
|
+
describe Architect::Runner do
|
6
|
+
|
7
|
+
it "should draw from file" do
|
8
|
+
Architect::Diagram.any_instance.should_receive(:draw)
|
9
|
+
Kernel.stub_chain(:open, :read).and_return("[User]")
|
10
|
+
architect = Architect::Runner.new("tmp/example.yuml", 'png', false)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to change extension" do
|
14
|
+
Kernel.stub_chain(:open, :read).and_return("[User]")
|
15
|
+
architect = Architect::Runner.new("test.yuml", "png", false)
|
16
|
+
architect.send(:change_extension, "test.yuml", "png").should == "test.png"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
config.order = 'random'
|
17
|
+
end
|
18
|
+
|
19
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
20
|
+
$: << File.join(APP_ROOT, 'lib/architect') # so rspec knows where your file could be
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uml_architect
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ibrahim Muhammad
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ruby-graphviz
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: listen
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.10.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.10.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-mocks
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Create UML Class Diagrams using text
|
112
|
+
email:
|
113
|
+
- ibrahim.mohammad@gmail.com
|
114
|
+
executables:
|
115
|
+
- architect
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- .gitignore
|
120
|
+
- .rspec
|
121
|
+
- Gemfile
|
122
|
+
- Guardfile
|
123
|
+
- LICENSE.txt
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- architect.gemspec
|
127
|
+
- bin/architect
|
128
|
+
- examples/aggregation.yuml
|
129
|
+
- examples/cardinality.yuml
|
130
|
+
- examples/class.yuml
|
131
|
+
- examples/class_with_details.yuml
|
132
|
+
- examples/color_and_utf8.yuml
|
133
|
+
- examples/composition.yuml
|
134
|
+
- examples/dependancies.yuml
|
135
|
+
- examples/directional_association.yuml
|
136
|
+
- examples/inheritance.yuml
|
137
|
+
- examples/interface.yuml
|
138
|
+
- examples/interface_inheritance.yuml
|
139
|
+
- examples/international_characters.yuml
|
140
|
+
- examples/notes.yuml
|
141
|
+
- examples/simple_association.yuml
|
142
|
+
- examples/something_meaty.yuml
|
143
|
+
- lib/architect.rb
|
144
|
+
- lib/architect/association.rb
|
145
|
+
- lib/architect/class.rb
|
146
|
+
- lib/architect/diagram.rb
|
147
|
+
- lib/architect/edge.rb
|
148
|
+
- lib/architect/node.rb
|
149
|
+
- lib/architect/parser.rb
|
150
|
+
- lib/architect/runner.rb
|
151
|
+
- lib/architect/version.rb
|
152
|
+
- spec/lib/association_spec.rb
|
153
|
+
- spec/lib/class_spec.rb
|
154
|
+
- spec/lib/diagram_spec.rb
|
155
|
+
- spec/lib/edge_spec.rb
|
156
|
+
- spec/lib/node_spec.rb
|
157
|
+
- spec/lib/parser_spec.rb
|
158
|
+
- spec/lib/runner_spec.rb
|
159
|
+
- spec/spec_helper.rb
|
160
|
+
homepage: https://github.com/whistler/architect
|
161
|
+
licenses:
|
162
|
+
- MIT
|
163
|
+
metadata: {}
|
164
|
+
post_install_message:
|
165
|
+
rdoc_options: []
|
166
|
+
require_paths:
|
167
|
+
- lib
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - '>='
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
requirements: []
|
179
|
+
rubyforge_project:
|
180
|
+
rubygems_version: 2.0.7
|
181
|
+
signing_key:
|
182
|
+
specification_version: 4
|
183
|
+
summary: Create UML Class Diagrams using a simple yUML like notation
|
184
|
+
test_files:
|
185
|
+
- spec/lib/association_spec.rb
|
186
|
+
- spec/lib/class_spec.rb
|
187
|
+
- spec/lib/diagram_spec.rb
|
188
|
+
- spec/lib/edge_spec.rb
|
189
|
+
- spec/lib/node_spec.rb
|
190
|
+
- spec/lib/parser_spec.rb
|
191
|
+
- spec/lib/runner_spec.rb
|
192
|
+
- spec/spec_helper.rb
|