archruby 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -0
- data/README.md +3 -18
- data/archruby.gemspec +1 -1
- data/lib/archruby.rb +2 -0
- data/lib/archruby/architecture/module_definition.rb +36 -2
- data/lib/archruby/architecture/parser.rb +6 -1
- data/lib/archruby/architecture/type_inference_checker.rb +69 -0
- data/lib/archruby/presenters/graph.rb +5 -5
- data/lib/archruby/ruby/parser.rb +66 -3
- data/lib/archruby/ruby/type_inference_dep.rb +14 -0
- data/lib/archruby/version.rb +1 -1
- data/spec/architecture/architecture_spec.rb +4 -5
- data/spec/architecture/module_definition_spec.rb +8 -3
- data/spec/dummy_app/app/controllers/application_controller.rb +6 -4
- data/spec/dummy_app/app/models/teste.rb +6 -4
- data/spec/dummy_app/app/models/user.rb +6 -2
- data/spec/fixtures/ruby_example_typeinference.rb +31 -0
- data/spec/ruby/parser_spec.rb +40 -5
- metadata +8 -6
- data/bin/constraints_breaks.yml +0 -29
- data/constraints_breaks.yml +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c24311c800c635316406aa7807888ed89f653ee
|
4
|
+
data.tar.gz: f7b2dbd14b1a69aadf72a8b79a6c85cfd85a37d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 612292c83300ff5930f47a2a7dd7d00d3e567036898bb7ac5471903e99c7d6884fc4b8a2e5738928ad99215317ba35b1098f580a0458fca099b3df6bf54f9bb3
|
7
|
+
data.tar.gz: f9b35b46ce70a018f8123a75b6a4989971d9dd5f9cc53914b7a76a840cb111524582ea6d7cbd3f987ede21fdefa8c89eff802332452b48f1f435b8206b930f5e
|
data/CHANGELOG.md
ADDED
File without changes
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Archruby
|
2
2
|
|
3
3
|
This gem aims to verify whether the system architecture is being respected by the developers. The application architecture is defined by the Software Architect through a YML file. After defining the architecture, you can use the tool to analyze if any part of the architecture is being broken in the system. To do this analysis it is necessary to pass the architecture definition file and the root path of the application to the ArchChecker executable. The ArchChecker will do an static scan in the application and generate an yaml file containing the violations. One picture of the entire application with all the communications will be generated either.
|
4
4
|
|
@@ -6,7 +6,7 @@ This gem aims to verify whether the system architecture is being respected by th
|
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
gem '
|
9
|
+
gem 'archruby'
|
10
10
|
|
11
11
|
And then execute:
|
12
12
|
|
@@ -14,19 +14,4 @@ And then execute:
|
|
14
14
|
|
15
15
|
Or install it yourself as:
|
16
16
|
|
17
|
-
$ gem install
|
18
|
-
|
19
|
-
## Usage
|
20
|
-
|
21
|
-
### Defining the architecture
|
22
|
-
|
23
|
-
### Invoking the arch_ckecker executable
|
24
|
-
|
25
|
-
|
26
|
-
## Contributing
|
27
|
-
|
28
|
-
1. Fork it
|
29
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
-
5. Create new Pull Request
|
17
|
+
$ gem install archruby
|
data/archruby.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["sergiohenriquetp@gmail.com"]
|
11
11
|
spec.description = %q{Compliance and Architectural Visualization in Ruby systems}
|
12
12
|
spec.summary = %q{Compliance and Architectural Visualization in Ruby systems}
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "http://aserg.labsoft.dcc.ufmg.br/archruby/"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
data/lib/archruby.rb
CHANGED
@@ -6,8 +6,10 @@ require 'archruby/ruby/parser'
|
|
6
6
|
require 'archruby/ruby/std_library'
|
7
7
|
require 'archruby/ruby/core_library'
|
8
8
|
require 'archruby/ruby/var_propagation'
|
9
|
+
require 'archruby/ruby/type_inference_dep'
|
9
10
|
require 'archruby/architecture/file_content'
|
10
11
|
require 'archruby/architecture/module_definition'
|
12
|
+
require 'archruby/architecture/type_inference_checker'
|
11
13
|
require 'archruby/architecture/dependency'
|
12
14
|
require 'archruby/architecture/constraint_break'
|
13
15
|
require 'archruby/architecture/architecture'
|
@@ -6,7 +6,8 @@ module Archruby
|
|
6
6
|
ALLOWED_CONSTRAINTS = ['required', 'allowed', 'forbidden']
|
7
7
|
|
8
8
|
attr_reader :name, :allowed_modules, :required_modules, :forbidden_modules,
|
9
|
-
:dependencies, :classes_and_dependencies
|
9
|
+
:dependencies, :classes_and_dependencies, :class_methods_and_deps,
|
10
|
+
:class_methods_calls
|
10
11
|
|
11
12
|
attr_accessor :classes
|
12
13
|
|
@@ -21,6 +22,8 @@ module Archruby
|
|
21
22
|
@classes = []
|
22
23
|
@dependencies = []
|
23
24
|
@classes_and_dependencies = []
|
25
|
+
@class_methods_and_deps = []
|
26
|
+
@class_methods_calls = []
|
24
27
|
extract_content_of_files
|
25
28
|
extract_dependencies
|
26
29
|
end
|
@@ -42,11 +45,42 @@ module Archruby
|
|
42
45
|
@classes << parser.classes
|
43
46
|
@dependencies << parser.dependencies
|
44
47
|
@classes_and_dependencies << parser.classes_and_dependencies
|
48
|
+
@class_methods_and_deps << parser.type_inference
|
49
|
+
@class_methods_calls << parser.method_calls
|
45
50
|
end
|
46
51
|
end
|
47
52
|
@classes << @config_definition.gems
|
48
53
|
@classes.flatten!
|
49
54
|
@dependencies.flatten!
|
55
|
+
@class_methods_and_deps.flatten!
|
56
|
+
@class_methods_calls.flatten!
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_new_dep class_name, type_inference_dep
|
60
|
+
if !type_inference_dep.class_dep.nil? && !already_has_dependency?(class_name, type_inference_dep.class_dep)
|
61
|
+
new_dep = Archruby::Architecture::Dependency.new(type_inference_dep.class_dep, nil)
|
62
|
+
@dependencies << type_inference_dep.class_dep
|
63
|
+
@classes_and_dependencies.each do |class_and_dep|
|
64
|
+
if class_and_dep.keys.first.eql?(class_name)
|
65
|
+
class_and_dep[class_and_dep.keys.first].push(new_dep)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def already_has_dependency? class_name, class_dep
|
72
|
+
has_dep = false
|
73
|
+
@classes_and_dependencies.each do |class_and_dep|
|
74
|
+
if class_and_dep.keys.first.eql?(class_name)
|
75
|
+
class_and_dep[class_and_dep.keys.first].each do |dependency|
|
76
|
+
if dependency.class_name.eql?(class_dep)
|
77
|
+
has_dep = true
|
78
|
+
break
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
has_dep
|
50
84
|
end
|
51
85
|
|
52
86
|
def is_mine? class_name
|
@@ -197,7 +231,7 @@ module Archruby
|
|
197
231
|
module_name = architecture.module_name(dependency.class_name)
|
198
232
|
next if architecture.is_ruby_internals? module_name
|
199
233
|
if module_name != self.name && !@config_definition.allowed_modules.include?(module_name)
|
200
|
-
next if /[A-Z]_+[A-Z]/.match(dependency.class_name)
|
234
|
+
next if /[A-Z]_+[A-Z]/.match(dependency.class_name) || @config_definition.required_modules.include?(module_name)
|
201
235
|
breaks << Archruby::Architecture::ConstraintBreak.new(
|
202
236
|
:type => 'divergence',
|
203
237
|
:class_origin => class_name,
|
@@ -10,6 +10,7 @@ module Archruby
|
|
10
10
|
@config_file = config_file_path
|
11
11
|
@base_path = base_path
|
12
12
|
@modules = []
|
13
|
+
@type_inference_checker = TypeInferenceChecker.new
|
13
14
|
parse
|
14
15
|
ruby_std_lib_module
|
15
16
|
ruby_core_module
|
@@ -22,11 +23,15 @@ module Archruby
|
|
22
23
|
begin
|
23
24
|
config_definition = Archruby::Architecture::ConfigDefinition.new module_name, definitions
|
24
25
|
module_definition = Archruby::Architecture::ModuleDefinition.new config_definition, @base_path
|
25
|
-
|
26
|
+
@type_inference_checker.add_method_deps module_definition.class_methods_and_deps
|
27
|
+
@type_inference_checker.add_method_calls module_definition.class_methods_calls
|
28
|
+
rescue Archruby::MultipleConstraints => e
|
26
29
|
STDOUT.puts "The config file is not right: #{e.msg} | err_code: #{e.status_code} | module_definition: #{module_name}"
|
27
30
|
exit(e.status_code)
|
28
31
|
end
|
29
32
|
@modules << module_definition
|
33
|
+
@type_inference_checker.verify_types
|
34
|
+
@type_inference_checker.add_new_deps @modules
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Archruby
|
2
|
+
module Architecture
|
3
|
+
|
4
|
+
class TypeInferenceChecker
|
5
|
+
attr_reader :method_and_deps, :method_calls
|
6
|
+
|
7
|
+
def initialize method_and_deps = nil, method_calls = nil
|
8
|
+
@method_and_deps = []
|
9
|
+
@method_calls = []
|
10
|
+
@method_and_deps = method_and_deps unless method_and_deps.nil?
|
11
|
+
@method_calls = method_calls unless method_calls.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_method_deps method_deps
|
15
|
+
@method_and_deps << method_deps
|
16
|
+
@method_and_deps.flatten!
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_method_calls method_calls
|
20
|
+
@method_calls << method_calls
|
21
|
+
@method_calls.flatten!
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_new_deps modules
|
25
|
+
@method_and_deps.each do |dep|
|
26
|
+
modules.each do |modl|
|
27
|
+
if !dep[:class_name].nil? && modl.is_mine?(dep[:class_name])
|
28
|
+
dep[:dep].each do |class_dep|
|
29
|
+
modl.add_new_dep dep[:class_name], class_dep
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def verify_types
|
37
|
+
3.times do
|
38
|
+
@method_calls.each do |method_call|
|
39
|
+
if !method_call[:method_call_params].nil?
|
40
|
+
method_call[:method_call_params].each do |param|
|
41
|
+
if method_call[:method_arguments] && method_call[:method_arguments].include?(param)
|
42
|
+
param_position = method_call[:method_arguments].index param
|
43
|
+
if !param_position.nil?
|
44
|
+
@method_and_deps.each do |dep|
|
45
|
+
if dep[:class_name] == method_call[:class]
|
46
|
+
class_dep = dep[:dep][param_position]
|
47
|
+
if class_dep
|
48
|
+
new_dep = Archruby::Ruby::TypeInferenceDep.new(
|
49
|
+
:class_dep => class_dep.class_dep
|
50
|
+
)
|
51
|
+
add_method_deps([{
|
52
|
+
:class_name => method_call[:class_call],
|
53
|
+
:method_name => method_call[:method_call],
|
54
|
+
:dep => [new_dep] # tem que ser adicionado na posicao param_position
|
55
|
+
}])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -103,11 +103,11 @@ module Archruby
|
|
103
103
|
next if module_definiton.name == Archruby::Ruby::STD_LIB_NAME || module_definiton.name == Archruby::Ruby::CORE_LIB_NAME
|
104
104
|
module_origin = module_definiton.is_empty? ? "#{module_definiton.name}\n [empty]" : module_definiton.name
|
105
105
|
node_origin = nodes[module_origin]
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
106
|
+
puts module_definiton.name.inspect
|
107
|
+
puts module_definiton.classes.inspect
|
108
|
+
puts module_definiton.dependencies.inspect
|
109
|
+
puts module_definiton.classes_and_dependencies.inspect
|
110
|
+
puts
|
111
111
|
module_definiton.allowed_modules.each do |allowed_module_name|
|
112
112
|
module_target = allowed_module_name
|
113
113
|
node_dest = nodes[allowed_module_name]
|
data/lib/archruby/ruby/parser.rb
CHANGED
@@ -5,7 +5,8 @@ module Archruby
|
|
5
5
|
module Ruby
|
6
6
|
|
7
7
|
class Parser < SexpInterpreter
|
8
|
-
attr_reader :dependencies, :classes, :classes_and_dependencies
|
8
|
+
attr_reader :dependencies, :classes, :classes_and_dependencies,
|
9
|
+
:type_inference, :method_calls
|
9
10
|
|
10
11
|
def initialize content
|
11
12
|
super()
|
@@ -17,6 +18,8 @@ module Archruby
|
|
17
18
|
@module_names = []
|
18
19
|
@complete_class_name = []
|
19
20
|
@var_propagation = Archruby::Ruby::VarPropagation.new
|
21
|
+
@type_inference = []
|
22
|
+
@method_calls = []
|
20
23
|
parse
|
21
24
|
end
|
22
25
|
|
@@ -95,18 +98,72 @@ module Archruby
|
|
95
98
|
def process_call exp
|
96
99
|
_, receiver, method_name, *args = exp
|
97
100
|
process receiver
|
98
|
-
|
99
101
|
if receiver && (receiver[0] == :const || receiver[0] == :colon2)
|
100
102
|
if @variables
|
101
103
|
@var_propagation.push @variables.last, exp.line, @dependencies.last
|
102
104
|
end
|
103
105
|
end
|
104
|
-
|
106
|
+
build_type_inference(receiver, method_name, args, exp.line)
|
107
|
+
args.map! {|sub_tree| process sub_tree}
|
108
|
+
end
|
109
|
+
|
110
|
+
def build_call_history receiver, method_name, params_name
|
111
|
+
@method_calls << {
|
112
|
+
:class => @classes.last,
|
113
|
+
:method => @current_method_name,
|
114
|
+
:method_arguments => @current_arguments,
|
115
|
+
:class_call => receiver,
|
116
|
+
:method_call => method_name,
|
117
|
+
:method_call_params => params_name
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
def build_type_inference receiver, method_name, params, line_num
|
122
|
+
if !@local_types.nil? && receiver && receiver[0] == :lvar
|
123
|
+
receiver = @local_types[receiver[1]]
|
124
|
+
params_name = []
|
125
|
+
deps = []
|
126
|
+
params.each do |param|
|
127
|
+
if param[0] == :lvar
|
128
|
+
params_name << param[1]
|
129
|
+
type_inference = TypeInferenceDep.new(
|
130
|
+
:class_source => @classes.last,
|
131
|
+
:class_dep => @local_types[param[1]],
|
132
|
+
:line_source_num => line_num
|
133
|
+
)
|
134
|
+
deps << type_inference
|
135
|
+
elsif param[0] == :call
|
136
|
+
process param
|
137
|
+
type_inference = TypeInferenceDep.new(
|
138
|
+
:class_source => @classes.last,
|
139
|
+
:class_dep => @dependencies.last,
|
140
|
+
:line_source_num => line_num
|
141
|
+
)
|
142
|
+
deps << type_inference
|
143
|
+
end
|
144
|
+
end
|
145
|
+
build_call_history(receiver, method_name, params_name)
|
146
|
+
@type_inference << {
|
147
|
+
:class_name => receiver,
|
148
|
+
:method_name => method_name,
|
149
|
+
:dep => deps
|
150
|
+
} if deps.size >= 1
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def extract_arguments arguments
|
155
|
+
_, *arg_vars = arguments
|
156
|
+
if arg_vars[0].class == Symbol
|
157
|
+
@current_arguments = arg_vars
|
158
|
+
end
|
105
159
|
end
|
106
160
|
|
107
161
|
def process_defn exp
|
108
162
|
@variables = []
|
163
|
+
@local_types = {}
|
109
164
|
_, method_name, method_arguments, *args = exp
|
165
|
+
@current_method_name = method_name
|
166
|
+
extract_arguments(method_arguments)
|
110
167
|
process method_arguments
|
111
168
|
args.map! {|sub_tree| process sub_tree}
|
112
169
|
@var_propagation.vars.each do |var|
|
@@ -121,12 +178,18 @@ module Archruby
|
|
121
178
|
end
|
122
179
|
@var_propagation = Archruby::Ruby::VarPropagation.new
|
123
180
|
@variables = []
|
181
|
+
@current_method_name = nil
|
182
|
+
@current_arguments = nil
|
124
183
|
end
|
125
184
|
|
126
185
|
def process_lasgn exp
|
127
186
|
_, variable_name, *args = exp
|
187
|
+
const_access = args[0][0] == :call unless args[0].nil?
|
128
188
|
@variables.push(variable_name) if @variables
|
129
189
|
args.map! {|sub_tree| process sub_tree}
|
190
|
+
if @local_types.class == Hash && const_access
|
191
|
+
@local_types[variable_name] = @dependencies.last
|
192
|
+
end
|
130
193
|
end
|
131
194
|
|
132
195
|
def process_lit exp
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Archruby
|
2
|
+
module Ruby
|
3
|
+
class TypeInferenceDep
|
4
|
+
|
5
|
+
attr_reader :class_source, :class_dep, :line_source_num
|
6
|
+
|
7
|
+
def initialize options
|
8
|
+
@class_source = options[:class_source]
|
9
|
+
@class_dep = options[:class_dep]
|
10
|
+
@line_source_num = options[:line_source_num]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/archruby/version.rb
CHANGED
@@ -11,7 +11,7 @@ describe Archruby::Architecture::Architecture do
|
|
11
11
|
|
12
12
|
it 'detect the amount of architecture erosion correctly' do
|
13
13
|
architecture.verify
|
14
|
-
architecture.constraints_breaks.count.should ==
|
14
|
+
architecture.constraints_breaks.count.should == 7
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'raise and error if how_many_break is called without verify the architecture' do
|
@@ -20,15 +20,14 @@ describe Archruby::Architecture::Architecture do
|
|
20
20
|
|
21
21
|
it 'return the amount of constraint breaks correctly' do
|
22
22
|
architecture.verify
|
23
|
-
puts architecture.constraints_breaks.inspect
|
24
23
|
controller_breaks = architecture.how_many_break "controller", "facebook", Archruby::Architecture::ConstraintBreak::DIVERGENCE
|
25
|
-
controller_breaks.should be_eql(
|
24
|
+
controller_breaks.should be_eql(2)
|
26
25
|
|
27
26
|
controller_breaks = architecture.how_many_break "model", "activerecord", Archruby::Architecture::ConstraintBreak::ABSENSE
|
28
27
|
controller_breaks.should be_eql(2)
|
29
28
|
|
30
29
|
controller_breaks = architecture.how_many_break "model", "facebook", Archruby::Architecture::ConstraintBreak::DIVERGENCE
|
31
|
-
controller_breaks.should be_eql(
|
30
|
+
controller_breaks.should be_eql(2)
|
32
31
|
|
33
32
|
controller_breaks = architecture.how_many_break "view", "model", Archruby::Architecture::ConstraintBreak::DIVERGENCE
|
34
33
|
controller_breaks.should be_eql(1)
|
@@ -42,7 +41,7 @@ describe Archruby::Architecture::Architecture do
|
|
42
41
|
end
|
43
42
|
|
44
43
|
it 'return the correct amount of time that an module access another module' do
|
45
|
-
architecture.how_many_access_to("controller", "model").should be_eql(
|
44
|
+
architecture.how_many_access_to("controller", "model").should be_eql(4)
|
46
45
|
architecture.how_many_access_to("model", "controller").should be_eql(1)
|
47
46
|
end
|
48
47
|
end
|
@@ -13,17 +13,23 @@ describe Archruby::Architecture::ModuleDefinition do
|
|
13
13
|
module_definition.classes.should include("User")
|
14
14
|
module_definition.dependencies.should include("ActiveRecord::Base")
|
15
15
|
module_definition.dependencies.should include("OutraClasse::De::Teste")
|
16
|
-
puts module_definition.classes_and_dependencies.first.should be_eql({})
|
17
16
|
module_definition.classes_and_dependencies[1].keys.should include("Teste")
|
18
17
|
module_definition.classes_and_dependencies.last.keys.should include("User")
|
19
18
|
end
|
20
19
|
|
20
|
+
it 'return true if the module has a class dependency' do
|
21
|
+
base_directory = File.expand_path('../../dummy_app/', __FILE__)
|
22
|
+
config_definition = Archruby::Architecture::ConfigDefinition.new 'model', parsed_yaml['model']
|
23
|
+
module_definition = Archruby::Architecture::ModuleDefinition.new(config_definition, base_directory)
|
24
|
+
module_definition.already_has_dependency?("User", "ActiveRecord::Base").should be_true
|
25
|
+
module_definition.already_has_dependency?("User", "ClassQualquer").should be_false
|
26
|
+
end
|
27
|
+
|
21
28
|
it 'build the dependencies correctly' do
|
22
29
|
base_directory = File.expand_path('../../dummy_app/', __FILE__)
|
23
30
|
config_definition = Archruby::Architecture::ConfigDefinition.new 'model', parsed_yaml['model']
|
24
31
|
module_definition = Archruby::Architecture::ModuleDefinition.new(config_definition, base_directory)
|
25
32
|
module_definition.dependencies.count.should be_eql(6)
|
26
|
-
module_definition.dependencies.should include("Koala::Facebook::API")
|
27
33
|
module_definition.dependencies.should include("OutraClasse::De::Teste")
|
28
34
|
module_definition.dependencies.should include("ActiveRecord::Base")
|
29
35
|
end
|
@@ -51,7 +57,6 @@ describe Archruby::Architecture::ModuleDefinition do
|
|
51
57
|
config_definition = Archruby::Architecture::ConfigDefinition.new 'model', parsed_yaml['model']
|
52
58
|
module_definition = Archruby::Architecture::ModuleDefinition.new(config_definition, base_directory)
|
53
59
|
required_breaks = module_definition.verify_required architecture
|
54
|
-
puts required_breaks.inspect
|
55
60
|
required_breaks.count.should == 2
|
56
61
|
required_breaks.first.class_origin.should == "Teste::Testando"
|
57
62
|
required_breaks.last.class_origin.should == "Teste"
|
@@ -2,15 +2,17 @@ class ApplicationController < ActionController::Base
|
|
2
2
|
# Prevent CSRF attacks by raising an exception.
|
3
3
|
# For APIs, you may want to use :null_session instead.
|
4
4
|
protect_from_forgery with: :exception
|
5
|
-
|
5
|
+
|
6
6
|
def break_facebook_looker
|
7
|
-
|
7
|
+
graph = Koala::Facebook::API.new("access_token_qualquer")
|
8
|
+
a = Teste.new
|
9
|
+
a.method(graph)
|
8
10
|
end
|
9
|
-
|
11
|
+
|
10
12
|
def access_an_user_model
|
11
13
|
@users = User.all
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
def access_an_teste_model
|
15
17
|
@teste = Teste.new
|
16
18
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
class Teste
|
2
2
|
include ClassedeTeste
|
3
3
|
|
4
|
-
def method
|
4
|
+
def method param
|
5
5
|
a = OutraClasse::De::Teste.new
|
6
|
+
b = User.new
|
7
|
+
b.metodo_teste param
|
6
8
|
end
|
7
|
-
|
9
|
+
|
8
10
|
def search_facebook
|
9
|
-
|
11
|
+
|
10
12
|
end
|
11
|
-
end
|
13
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Test
|
2
|
+
def metodo_test c, d, a
|
3
|
+
d = 1
|
4
|
+
a = Testa::Com::Classe.new
|
5
|
+
param = Param.new
|
6
|
+
d = ::Vai::La.new
|
7
|
+
a.method(param, d)
|
8
|
+
b = Teste.new
|
9
|
+
b.vai(Bosta::RALA.new)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Testa::Com::Classe
|
14
|
+
def method x
|
15
|
+
b = OutraClasse.new
|
16
|
+
b.chama(x)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Param
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class Testa
|
25
|
+
def method klass = A.new
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class NewClasse
|
31
|
+
end
|
data/spec/ruby/parser_spec.rb
CHANGED
@@ -2,25 +2,60 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Archruby::Ruby::Parser do
|
4
4
|
let(:ruby_content_file) { File.open(File.expand_path('../../fixtures/ruby_example.rb', __FILE__), 'r').read }
|
5
|
+
let(:ruby_content_file_typeinference) { File.open(File.expand_path('../../fixtures/ruby_example_typeinference.rb', __FILE__), 'r').read }
|
5
6
|
let(:ruby_parser) { Archruby::Ruby::Parser.new(ruby_content_file) }
|
6
7
|
|
8
|
+
it 'should parse ruby files correctly and store type information' do
|
9
|
+
parser = Archruby::Ruby::Parser.new ruby_content_file_typeinference
|
10
|
+
# class_methods_dep = parser.type_inference
|
11
|
+
# class_methods_calls = parser.method_calls
|
12
|
+
# typer = Archruby::Architecture::TypeInferenceChecker.new class_methods_dep, class_methods_calls
|
13
|
+
# class_methods_calls.each do |method_call|
|
14
|
+
# if !method_call[:method_call_params].nil?
|
15
|
+
# method_call[:method_call_params].each do |param|
|
16
|
+
# if method_call[:method_arguments].include? param
|
17
|
+
# param_position = method_call[:method_arguments].index param
|
18
|
+
# if !param_position.nil?
|
19
|
+
# class_methods_dep.each do |dep|
|
20
|
+
# if dep[:class_name] == method_call[:class]
|
21
|
+
# class_dep = dep[:dep][param_position]
|
22
|
+
# new_dep = Archruby::Ruby::TypeInferenceDep.new(
|
23
|
+
# :class_dep => class_dep.class_dep
|
24
|
+
# )
|
25
|
+
# class_methods_dep << {
|
26
|
+
# :class_name => method_call[:class_call],
|
27
|
+
# :method_name => method_call[:method_call],
|
28
|
+
# :dep => new_dep
|
29
|
+
# }
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# typer.verify_types
|
38
|
+
# puts
|
39
|
+
# puts class_methods_dep.inspect
|
40
|
+
# puts class_methods_calls.inspect
|
41
|
+
# puts
|
42
|
+
# puts 'TYPER'
|
43
|
+
# puts typer.method_and_deps.inspect
|
44
|
+
# puts typer.method_calls.inspect
|
45
|
+
end
|
46
|
+
|
7
47
|
it 'should parse ruby files correctly and return the dependencies' do
|
8
48
|
ruby_parser.dependencies.should include("BostadeTeste::Testado")
|
9
49
|
ruby_parser.dependencies.should include("BostaRala")
|
10
50
|
ruby_parser.dependencies.should include("TesteClasse")
|
11
51
|
ruby_parser.dependencies.should include("BostaQualquer")
|
12
52
|
ruby_parser.dependencies.should include("ClasseDeTeste::Em::OutroModulo::NaPQP")
|
13
|
-
puts "Dependencias"
|
14
|
-
puts ruby_parser.dependencies.inspect
|
15
|
-
puts
|
16
53
|
end
|
17
54
|
|
18
55
|
it 'extract correct class from file' do
|
19
56
|
ruby_parser.classes.should include("Teste")
|
20
57
|
ruby_parser.classes.should include("BostaOutra")
|
21
58
|
ruby_parser.classes.should include("Multiple::Access::Teste")
|
22
|
-
puts "Classes"
|
23
|
-
puts ruby_parser.classes.inspect
|
24
59
|
end
|
25
60
|
|
26
61
|
it 'extract correct classes and depencies' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: archruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergio Henrique
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -99,19 +99,17 @@ email:
|
|
99
99
|
- sergiohenriquetp@gmail.com
|
100
100
|
executables:
|
101
101
|
- archruby
|
102
|
-
- constraints_breaks.yml
|
103
102
|
extensions: []
|
104
103
|
extra_rdoc_files: []
|
105
104
|
files:
|
106
105
|
- ".gitignore"
|
106
|
+
- CHANGELOG.md
|
107
107
|
- Gemfile
|
108
108
|
- LICENSE.txt
|
109
109
|
- README.md
|
110
110
|
- Rakefile
|
111
111
|
- archruby.gemspec
|
112
112
|
- bin/archruby
|
113
|
-
- bin/constraints_breaks.yml
|
114
|
-
- constraints_breaks.yml
|
115
113
|
- lib/archruby.rb
|
116
114
|
- lib/archruby/architecture/architecture.rb
|
117
115
|
- lib/archruby/architecture/config_definition.rb
|
@@ -120,12 +118,14 @@ files:
|
|
120
118
|
- lib/archruby/architecture/file_content.rb
|
121
119
|
- lib/archruby/architecture/module_definition.rb
|
122
120
|
- lib/archruby/architecture/parser.rb
|
121
|
+
- lib/archruby/architecture/type_inference_checker.rb
|
123
122
|
- lib/archruby/presenters/graph.rb
|
124
123
|
- lib/archruby/presenters/text.rb
|
125
124
|
- lib/archruby/presenters/yaml.rb
|
126
125
|
- lib/archruby/ruby/core_library.rb
|
127
126
|
- lib/archruby/ruby/parser.rb
|
128
127
|
- lib/archruby/ruby/std_library.rb
|
128
|
+
- lib/archruby/ruby/type_inference_dep.rb
|
129
129
|
- lib/archruby/ruby/var_propagation.rb
|
130
130
|
- lib/archruby/version.rb
|
131
131
|
- spec/architecture/architecture_spec.rb
|
@@ -195,10 +195,11 @@ files:
|
|
195
195
|
- spec/dummy_app/vendor/assets/stylesheets/.keep
|
196
196
|
- spec/fixtures/new_arch_definition.yml
|
197
197
|
- spec/fixtures/ruby_example.rb
|
198
|
+
- spec/fixtures/ruby_example_typeinference.rb
|
198
199
|
- spec/ruby/parser_spec.rb
|
199
200
|
- spec/ruby/var_propagation_spec.rb
|
200
201
|
- spec/spec_helper.rb
|
201
|
-
homepage:
|
202
|
+
homepage: http://aserg.labsoft.dcc.ufmg.br/archruby/
|
202
203
|
licenses:
|
203
204
|
- MIT
|
204
205
|
metadata: {}
|
@@ -290,6 +291,7 @@ test_files:
|
|
290
291
|
- spec/dummy_app/vendor/assets/stylesheets/.keep
|
291
292
|
- spec/fixtures/new_arch_definition.yml
|
292
293
|
- spec/fixtures/ruby_example.rb
|
294
|
+
- spec/fixtures/ruby_example_typeinference.rb
|
293
295
|
- spec/ruby/parser_spec.rb
|
294
296
|
- spec/ruby/var_propagation_spec.rb
|
295
297
|
- spec/spec_helper.rb
|
data/bin/constraints_breaks.yml
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- divergence:
|
3
|
-
class_origin: TwitterController
|
4
|
-
line_origin: 21
|
5
|
-
class_target: Twitter::REST::Client
|
6
|
-
module_origin: controller
|
7
|
-
module_target: twitter
|
8
|
-
message: accessing a module not allowed
|
9
|
-
- divergence:
|
10
|
-
class_origin: Teste
|
11
|
-
line_origin: 3
|
12
|
-
class_target: SearchTerm
|
13
|
-
module_origin: view
|
14
|
-
module_target: model
|
15
|
-
message: accessing a module which is forbidden
|
16
|
-
- absence:
|
17
|
-
class_origin: TesteClass
|
18
|
-
line_origin:
|
19
|
-
class_target:
|
20
|
-
module_origin: model
|
21
|
-
module_target: activerecord
|
22
|
-
message: not implement a required module
|
23
|
-
- divergence:
|
24
|
-
class_origin: TwitterIntegration
|
25
|
-
line_origin: 19
|
26
|
-
class_target: PdfIntegration
|
27
|
-
module_origin: integracao_twitter
|
28
|
-
module_target: integracao_pdf
|
29
|
-
message: accessing a module not allowed
|
data/constraints_breaks.yml
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- divergence:
|
3
|
-
class_origin: ApplicationController
|
4
|
-
line_origin: 1
|
5
|
-
class_target: ActionController::Base
|
6
|
-
module_origin: controller
|
7
|
-
module_target: ''
|
8
|
-
message: accessing a module not allowed
|
9
|
-
- divergence:
|
10
|
-
class_origin: ViewTest
|
11
|
-
line_origin: 3
|
12
|
-
class_target: User
|
13
|
-
module_origin: view
|
14
|
-
module_target: model
|
15
|
-
message: accessing a module which is forbidden
|
16
|
-
- absence:
|
17
|
-
class_origin: Teste
|
18
|
-
line_origin:
|
19
|
-
class_target:
|
20
|
-
module_origin: model
|
21
|
-
module_target: activerecord
|
22
|
-
message: not implement a required module
|