rubydeps 0.9.1.pre → 0.9.2.pre

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -21,3 +21,5 @@ tmp
21
21
  *.svg
22
22
 
23
23
  ## PROJECT::SPECIFIC
24
+ rubydeps.dump
25
+ lib/*.bundle
data/README.md CHANGED
@@ -2,7 +2,10 @@
2
2
  rubydeps
3
3
  ========
4
4
 
5
- A tool to create class dependency graphs from test suites
5
+ A tool to create class dependency graphs from test suites.
6
+
7
+ I think this is more useful than static analysis of the code base because of the high dynamic aspects of the language
8
+
6
9
 
7
10
  Sample output
8
11
  -------------
@@ -10,60 +13,57 @@ Sample output
10
13
  This is the result of running rubydeps on the [Rake](https://github.com/jimweirich/rake) tests:
11
14
 
12
15
  ```bash
13
- rubydeps testunit --class_name_filter='^Rake'
16
+ rubydeps --class_name_filter='^Rake'
14
17
  ```
15
18
 
16
19
  ![Rake dependencies](https://github.com/dcadenas/rubydeps/raw/master/rake-deps.png)
17
20
 
21
+ Usage
22
+ ---------------
18
23
 
19
- Command line usage
20
- ------------------
24
+ Rubydeps will run your test suite to record the call graph of your project and use it to create a [Graphviz](http://www.graphviz.org) dot graph.
21
25
 
26
+ 1. Add Rubydeps to your `Gemfile` and `bundle install`:
22
27
 
23
- Rubydeps will run your test suite to record the call graph of your project and use it to create a dot graph.
28
+ gem 'rubydeps', :group => :test
24
29
 
25
- First of all, be sure to step into the root directory of your project, rubydeps searches for ./spec or ./test dirs from there.
26
- For example, if we want to graph the Rails activemodel dependency graph we'd cd to rails/activemodel and from there we'd write:
30
+ 2. Launch Rubydeps by inserting this line in your `test/test_helper.rb` (*or `spec_helper.rb`, cucumber `env.rb`, or whatever
31
+ your preferred test framework uses*):
27
32
 
28
- ```bash
29
- rubydeps testunit #to run Test::Unit tests
30
- ```
33
+ Rubydeps.start
31
34
 
32
- or
35
+ Notice that this will slow down your tests so consider adding a conditional bound to some ENV variable or just remove the line when you are done.
33
36
 
34
- ```bash
35
- rubydeps rspec #to run RSpec tests
36
- ```
37
+ 3. Run your tests, a file named rubydeps.dump will be created in the project root.
37
38
 
38
- or
39
+ 4. The next step is reading the dump file to generate the graphviz dot graph `rubydeps.dot` with any filter you specify.
39
40
 
40
- ```bash
41
- rubydeps rspec2 #to run RSpec 2 tests
42
- ```
41
+ ```bash
42
+ rubydeps --path_filter='app/models'
43
+ ```
43
44
 
44
- This will output a rubydeps.dot. You can convert the dot file to any image format you like using the dot utility that comes with the graphviz installation e.g.:
45
+ 5. Now you are in [Graphviz](http://www.graphviz.org) realm. You can convert the dot file to any image format with your prefered orientations and layouts with the dot utility that comes with the graphviz installation e.g.:
45
46
 
46
- ```bash
47
- dot -Tsvg rubydeps.dot > rubydeps.svg
48
- ```
47
+ ```bash
48
+ dot -Tsvg rubydeps.dot > rubydeps.svg
49
+ ```
49
50
 
50
- Notice that sometimes you may have missing dependencies as we graph the dependencies exercised by your tests so it's a quick bird's eye view to check your project coverage.
51
+ Notice that sometimes you may have missing dependencies as we graph the dependencies exercised by your tests so you can use it as a quick bird's eye view of your project test coverage.
51
52
 
52
53
  ### Command line options
53
54
 
54
- The `--path_filter` option specifies a regexp that matches the path of the files you are interested in analyzing. For example you could have filters like `'project_name/app|project_name/lib'` to analyze only code that is located in the `app` and `lib` dirs or as an alternative you could just exclude some directory you are not interested using a negative regexp like `'project_name(?!.*test)'`
55
+ * The `--path_filter` option specifies a regexp that matches the path of the files you are interested in analyzing. For example you could have filters like `'project_name/app|project_name/lib'` to analyze only code that is located in the `app` and `lib` dirs or as an alternative you could just exclude some directory you are not interested using a negative regexp like `'project_name(?!.*test)'`
55
56
 
56
- The `--class_name_filter` option is similar to the `--path_filter` options except that the regexp is matched against the class names (i.e. graph node names).
57
+ * The `--class_name_filter` option is similar to the `--path_filter` options except that the regexp is matched against the class names (i.e. graph node names).
57
58
 
58
- The `--to_file` option dumps the dependency graph data to a file so you can do filtering later, it does not create a dot file.
59
+ * The `--from_file` option is used to specify the dump file generated after the test (or block) run so you can try different filters without needing to rerun the tests. e.g.:
59
60
 
60
- The `--from_file` option is only available when you don't specify a test command. Its argument is the file dumped through `--to_file` in a previous run. When you use this option the tests (or block) are not ran, the dependency graph is loaded directly from the file. This is useful to avoid rerunning code that didn't change just for the purpose of filtering with different combinations e.g.:
61
+ ```bash
62
+ rubydeps --from_file='rubydeps.dump' --path_filter='app/models'
63
+ rubydeps --from_file='rubydeps.dump' --path_filter='app/models|app/controllers'
64
+ ```
61
65
 
62
- ```bash
63
- rubydeps rspec2 --to_file='dependencies.dump'
64
- rubydeps --from_file='dependencies.dump' --path_filter='app/models'
65
- rubydeps --from_file='dependencies.dump' --path_filter='app/models|app/controllers'
66
- ```
66
+ If you didn't rename the file you can skip this option as it will use the default `rubydeps.dump`
67
67
 
68
68
  Library usage
69
69
  -------------
@@ -73,7 +73,7 @@ Just require rubydeps and pass a block to analyze to the `analyze` method.
73
73
  ```ruby
74
74
  require 'rubydeps'
75
75
 
76
- Rubydeps.analyze(:path_filter => path_filter_regexp, :class_name_filter => class_name_filter_regexp, :to_file => "dependencies.dump") do
76
+ Rubydeps.analyze(:path_filter => path_filter_regexp, :class_name_filter => class_name_filter_regexp, :to_file => "rubydeps.dump") do
77
77
  # your code goes here
78
78
  end
79
79
  ```
@@ -85,20 +85,20 @@ Installation
85
85
  gem install rubydeps --pre
86
86
  ```
87
87
 
88
- Rubydeps now only supports ruby 1.9. If you need 1.8.x support then:
88
+ Rubydeps now only supports ruby 1.9.x. If you need 1.8.x support then:
89
89
 
90
90
  ```bash
91
91
  gem install rubydeps -v0.2.0
92
92
  ```
93
93
 
94
- Notice that in 0.2.0 you should use dot_for instead of analyze.
94
+ Notice that in 0.2.0 you should use `dot_for` instead of `analyze` and the dump functionality is missing.
95
95
 
96
96
  Dependencies
97
97
  ------------
98
98
 
99
- * rcov (only for version 0.2.0)
100
99
  * graphviz
101
100
  * ruby-graphviz
101
+ * rcov (only for version 0.2.0)
102
102
 
103
103
  Note on Patches/Pull Requests
104
104
  -----------------------------
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.1.pre
1
+ 0.9.2.pre
data/bin/rubydeps CHANGED
@@ -4,78 +4,16 @@ require 'thor'
4
4
 
5
5
  module Rubydeps
6
6
  class Runner < Thor
7
- desc "testunit", "Create the dependency graph after runnning the testunit tests"
8
- method_option :to_file, :type => :string
7
+ desc "", "Loads dependencies saved by a previous test run"
8
+ method_option :from_file, :type => :string, :default => Rubydeps.default_dump_file_name, :required => true
9
9
  method_option :path_filter, :type => :string, :default => `pwd`.chomp, :required => true
10
10
  method_option :class_name_filter, :type => :string, :default => '', :required => true
11
- def testunit
12
- require 'minitest/unit'
13
- require 'test/unit/assertions'
14
- require 'test/unit/testcase'
15
-
16
- $LOAD_PATH.unshift("#{`pwd`.chomp}/lib")
17
-
18
- #dirty hack so that minitest doesn't install the at_exit hook and we can run the tests in this same process
19
- ::MiniTest::Unit.class_variable_set("@@installed_at_exit", true)
20
-
21
- (Dir["./test/**/*_test.rb"] + Dir["./test/**/test_*.rb"]).each { |f| load f unless f =~ /^-/ }
22
-
23
- create_dependencies_dot_for(options) do
24
- ::MiniTest::Unit.new.run([])
25
- end
26
- end
27
-
28
- desc "rspec", "Create the dependency graph after runnning the rspec tests"
29
- method_option :to_file, :type => :string
30
- #TODO: this breaks when using underscores, investigate
31
- method_option :path_filter, :type => :string, :default => `pwd`.chomp, :required => true
32
- method_option :class_name_filter, :type => :string, :default => '', :required => true
33
- def rspec
34
- require 'spec'
35
-
36
- p = ::Spec::Runner::OptionParser.new($stderr, $stdout)
37
- p.parse(Dir["./spec/**/*_spec.rb"])
38
- op = p.options
39
-
40
- create_dependencies_dot_for(options) do
41
- ::Spec::Runner::CommandLine.run(op)
42
- end
43
- end
44
-
45
- desc "", "Loads dependencies saved by a --to_file option in a previous run. Doesn't run tests"
46
- method_option :from_file, :type => :string, :required => true
47
- method_option :path_filter, :type => :string, :default => `pwd`.chomp, :required => true
48
- method_option :class_name_filter, :type => :string, :default => '', :required => true
49
- default_task :load_deps
50
- def load_deps
51
- create_dependencies_dot_for(options)
52
- end
53
-
54
- desc "rspec2", "Create the dependency graph after runnning the rspec 2 tests"
55
- method_option :to_file, :type => :string
56
- method_option :path_filter, :type => :string, :default => `pwd`.chomp, :required => true
57
- method_option :class_name_filter, :type => :string, :default => '', :required => true
58
- def rspec2
59
- require 'rspec'
60
-
61
- op = ::RSpec::Core::ConfigurationOptions.new(Dir["./spec/**/*_spec.rb"])
62
- op.parse_options
63
-
64
- create_dependencies_dot_for(options) do
65
- ::RSpec::Core::CommandLine.new(op).run($stderr, $stdout)
66
- end
67
- end
68
-
69
- private
70
-
71
- def create_dependencies_dot_for(options)
11
+ default_task :create_dot
12
+ def create_dot
72
13
  ARGV.clear
73
14
  Rubydeps.analyze(:path_filter => Regexp.new(options[:path_filter]),
74
15
  :class_name_filter => Regexp.new(options[:class_name_filter]),
75
- :to_file => options[:to_file],
76
- :from_file => options[:from_file]) do
77
- yield if block_given?
78
- end
16
+ :from_file => options[:from_file])
79
17
  end
80
18
  end
81
19
  end
@@ -116,25 +116,24 @@ static int uniq_calling_arrays(VALUE called_class, VALUE calling_class_array, VA
116
116
  return ST_CONTINUE;
117
117
  }
118
118
 
119
- static VALUE analyze(VALUE self){
120
- if(rb_block_given_p()) {
121
- dependency_array = rb_ary_new();
122
- rb_global_variable(&dependency_array);
119
+ static VALUE start(VALUE self){
120
+ dependency_array = rb_ary_new();
121
+ rb_global_variable(&dependency_array);
123
122
 
124
- VALUE dependency_hash = rb_hash_new();
125
- rb_ary_push(dependency_array, dependency_hash);
123
+ VALUE dependency_hash = rb_hash_new();
124
+ rb_ary_push(dependency_array, dependency_hash);
126
125
 
127
- VALUE class_location_hash = rb_hash_new();
128
- rb_ary_push(dependency_array, class_location_hash);
126
+ VALUE class_location_hash = rb_hash_new();
127
+ rb_ary_push(dependency_array, class_location_hash);
129
128
 
130
- rb_add_event_hook(event_hook, RUBY_EVENT_CALL, Qnil);
131
- rb_yield(Qnil);
132
- rb_remove_event_hook(event_hook);
129
+ rb_add_event_hook(event_hook, RUBY_EVENT_CALL, Qnil);
133
130
 
134
- rb_hash_foreach(rb_ary_entry(dependency_array, 0), uniq_calling_arrays, 0);
135
- } else {
136
- rb_raise(rb_eArgError, "a block is required");
137
- }
131
+ return Qnil;
132
+ }
133
+
134
+ static VALUE result(VALUE self){
135
+ rb_remove_event_hook(event_hook);
136
+ rb_hash_foreach(rb_ary_entry(dependency_array, 0), uniq_calling_arrays, 0);
138
137
 
139
138
  return dependency_array;
140
139
  }
@@ -143,5 +142,6 @@ static VALUE rb_cCallSiteAnalyzer;
143
142
 
144
143
  void Init_call_site_analyzer(){
145
144
  rb_cCallSiteAnalyzer = rb_define_module("CallSiteAnalyzer");
146
- rb_define_singleton_method(rb_cCallSiteAnalyzer, "analyze", analyze, 0);
145
+ rb_define_singleton_method(rb_cCallSiteAnalyzer, "start", start, 0);
146
+ rb_define_singleton_method(rb_cCallSiteAnalyzer, "result", result, 0);
147
147
  }
data/lib/rubydeps.rb CHANGED
@@ -1,44 +1,61 @@
1
1
  require 'graphviz'
2
- require 'set'
3
2
  require 'call_site_analyzer'
4
3
 
5
4
  module Rubydeps
5
+ def self.start(install_at_exit = true)
6
+ CallSiteAnalyzer.start
7
+ at_exit { self.do_at_exit } if install_at_exit
8
+ end
9
+
6
10
  def self.analyze(options = {}, &block_to_analyze)
7
11
  dependency_hash, class_location_hash = dependency_hash_for(options, &block_to_analyze)
12
+ create_output_file(dependency_hash, class_location_hash, options)
13
+ end
14
+
15
+ def self.dependency_hash_for(options = {}, &block_to_analyze)
16
+ dependency_hash, class_location_hash = calculate_or_load_dependencies(options, &block_to_analyze)
17
+
18
+ apply_filters(dependency_hash, class_location_hash, options)
8
19
 
20
+ [normalize_class_names(dependency_hash), class_location_hash]
21
+ end
22
+
23
+ def self.create_output_file(dependency_hash, class_location_hash, options)
9
24
  if options[:to_file]
10
25
  File.open(options[:to_file], 'wb') do |f|
11
26
  f.write Marshal.dump([dependency_hash, class_location_hash])
12
27
  end
13
28
  else
14
- if dependency_hash
15
- g = GraphViz::new( "G", :use => 'dot', :mode => 'major', :rankdir => 'LR', :concentrate => 'true', :fontname => 'Arial')
16
- dependency_hash.each do |k,vs|
17
- if !k.empty? && !vs.empty?
18
- n1 = g.add_nodes(k.to_s)
19
- if vs.respond_to?(:each)
20
- vs.each do |v|
21
- unless v.empty?
22
- n2 = g.add_nodes(v.to_s)
23
- g.add_edges(n2, n1)
24
- end
25
- end
26
- end
27
- end
28
- end
29
+ create_dot_file(dependency_hash)
30
+ end
31
+ end
29
32
 
30
- g.output( :dot => "rubydeps.dot" )
31
- end
33
+ def self.do_at_exit
34
+ # Store the exit status of the test run since it goes away after calling the at_exit proc...
35
+ exit_status = if $!
36
+ $!.is_a?(SystemExit) ? $!.status : 1
32
37
  end
38
+
39
+ dependency_hash, class_location_hash = CallSiteAnalyzer.result
40
+ create_output_file(dependency_hash, class_location_hash, :to_file => Rubydeps.default_dump_file_name, :class_name_filter => /.*/, :path_filter => /.*/)
41
+
42
+ exit exit_status if exit_status
33
43
  end
34
44
 
35
- def self.dependency_hash_for(options = {}, &block_to_analyze)
36
- dependency_hash, class_location_hash = if options[:from_file]
37
- Marshal.load(File.binread(options[:from_file]))
38
- else
39
- CallSiteAnalyzer.analyze(&block_to_analyze)
40
- end
45
+ def self.calculate_or_load_dependencies(options, &block_to_analyze)
46
+ if options[:from_file]
47
+ Marshal.load(File.binread(options[:from_file]))
48
+ else
49
+ begin
50
+ self.start(false)
51
+ block_to_analyze.call()
52
+ ensure
53
+ return CallSiteAnalyzer.result
54
+ end
55
+ end
56
+ end
41
57
 
58
+ def self.apply_filters(dependency_hash, class_location_hash, options)
42
59
  path_filter = options.fetch(:path_filter, /.*/)
43
60
  class_name_filter = options.fetch(:class_name_filter, /.*/)
44
61
  classes_to_remove = get_classes_to_remove(dependency_hash, class_location_hash, path_filter, class_name_filter)
@@ -50,13 +67,6 @@ module Rubydeps
50
67
  dependency_hash[called_class].member? klass_to_remove
51
68
  end
52
69
 
53
- #transitive dependencies, hmmm, not sure is a good idea
54
- #if classes_calling_class_to_remove && !classes_calling_class_to_remove.empty?
55
- # classes_called_by_class_to_remove.each do |called_class|
56
- # dependency_hash[called_class] |= classes_calling_class_to_remove
57
- # end
58
- #end
59
-
60
70
  dependency_hash.delete(klass_to_remove)
61
71
  classes_called_by_class_to_remove.each do |called_class|
62
72
  if dependency_hash[called_class]
@@ -67,10 +77,34 @@ module Rubydeps
67
77
  end
68
78
  end
69
79
  end
80
+ end
81
+ end
82
+
83
+ def self.normalize_class_name(klass)
84
+ good_class_name = klass.gsub(/#<(.+):(.+)>/, 'Instance of \1')
85
+ good_class_name.gsub!(/\([^\)]*\)/, "")
86
+ good_class_name.gsub(/0x[\da-fA-F]+/, '(hex number)')
87
+ end
70
88
 
89
+ def self.create_dot_file(dependency_hash)
90
+ return unless dependency_hash
91
+
92
+ g = GraphViz::new( "G", :use => 'dot', :mode => 'major', :rankdir => 'LR', :concentrate => 'true', :fontname => 'Arial')
93
+ dependency_hash.each do |k,vs|
94
+ if !k.empty? && !vs.empty?
95
+ n1 = g.add_nodes(k.to_s)
96
+ if vs.respond_to?(:each)
97
+ vs.each do |v|
98
+ unless v.empty?
99
+ n2 = g.add_nodes(v.to_s)
100
+ g.add_edges(n2, n1)
101
+ end
102
+ end
103
+ end
104
+ end
71
105
  end
72
106
 
73
- [normalize_class_names(dependency_hash), class_location_hash]
107
+ g.output( :dot => "rubydeps.dot" )
74
108
  end
75
109
 
76
110
  def self.get_classes_to_remove(dependency_hash, class_location_hash, path_filter, class_name_filter)
@@ -84,9 +118,7 @@ module Rubydeps
84
118
  Hash[dependency_hash.map { |k,v| [normalize_class_name(k), v.map{|c| c == k ? nil : normalize_class_name(c)}.compact] }]
85
119
  end
86
120
 
87
- def self.normalize_class_name(klass)
88
- good_class_name = klass.gsub(/#<(.+):(.+)>/, 'Instance of \1')
89
- good_class_name.gsub!(/\([^\)]*\)/, "")
90
- good_class_name.gsub(/0x[\da-fA-F]+/, '(hex number)')
121
+ def self.default_dump_file_name
122
+ "rubydeps.dump"
91
123
  end
92
124
  end
data/rubydeps.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{rubydeps}
3
- s.version = "0.9.1.pre"
3
+ s.version = "0.9.2.pre"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["Daniel Cadenas"]
@@ -48,7 +48,7 @@ class Son
48
48
  end
49
49
 
50
50
  describe "Rubydeps" do
51
- include FileTestHelper
51
+
52
52
  it "should show the class level dependencies" do
53
53
  dependencies, _ = ::Rubydeps.dependency_hash_for do
54
54
  class IHaveAClassLevelDependency
@@ -59,18 +59,6 @@ describe "Rubydeps" do
59
59
  dependencies.should == {"Parent"=>["Son"]}
60
60
  end
61
61
 
62
- it "should create a dot file" do
63
- with_files do
64
- ::Rubydeps.analyze do
65
- class IHaveAClassLevelDependency
66
- Son.class_method
67
- end
68
- end
69
-
70
- File.read("rubydeps.dot").should match("digraph G")
71
- end
72
- end
73
-
74
62
  it "should be idempotent" do
75
63
  ::Rubydeps.dependency_hash_for do
76
64
  class IHaveAClassLevelDependency
@@ -112,73 +100,80 @@ describe "Rubydeps" do
112
100
  dependencies["GrandparentModule"].should == ["Grandparent"]
113
101
  end
114
102
 
115
- sample_dir_structure = {'path1/class_a.rb' => <<-CLASSA,
116
- require './path1/class_b'
117
- require './path2/class_c'
118
- class A
119
- def depend_on_b_and_c
120
- B.new.b
121
- C.new.c
122
- end
123
- end
124
- CLASSA
125
- 'path1/class_b.rb' => 'class B; def b; end end',
126
- 'path2/class_c.rb' => 'class C; def c; end end'}
103
+ it "should create correct dependencies for 2 instance methods called in a row" do
104
+ dependencies, _ = ::Rubydeps.dependency_hash_for do
105
+ Son.new.instance_method_calling_another_instance_method(Parent.new)
106
+ end
127
107
 
128
- it "should not filter classes when no filter is specified" do
129
- with_files(sample_dir_structure) do
130
- load './path1/class_a.rb'
108
+ dependencies.should == {"Parent"=>["Son"]}
109
+ end
131
110
 
132
- dependencies, _ = ::Rubydeps.dependency_hash_for do
133
- A.new.depend_on_b_and_c
134
- end
111
+ context "with a dumped dependencies file" do
112
+ include FileTestHelper
135
113
 
136
- dependencies.should == {"B"=>["A"], "C"=>["A"]}
137
- end
138
- end
114
+ sample_dir_structure = {'path1/class_a.rb' => <<-CLASSA,
115
+ require '#{File.dirname(__FILE__)}/../lib/rubydeps'
139
116
 
140
- it "should filter classes when a path filter is specified" do
141
- with_files(sample_dir_structure) do
142
- load './path1/class_a.rb'
117
+ require './path1/class_b'
118
+ require './path2/class_c'
119
+ class A
120
+ def depend_on_b_and_c
121
+ B.new.b
122
+ C.new.c
123
+ end
124
+ end
143
125
 
144
- dependencies, _ = ::Rubydeps.dependency_hash_for(:path_filter => /path1/) do
145
- A.new.depend_on_b_and_c
146
- end
126
+ Rubydeps.start
127
+ A.new.depend_on_b_and_c
128
+ CLASSA
129
+ 'path1/class_b.rb' => 'class B; def b; end end',
130
+ 'path2/class_c.rb' => 'class C; def c; end end'}
147
131
 
148
- dependencies.should == {"B"=>["A"]}
132
+ def run(command)
133
+ system("ruby -I#{File.dirname(__FILE__)}/../lib #{command}")
149
134
  end
150
- end
151
135
 
152
- it "should filter classes when a class name filter is specified" do
153
- with_files(sample_dir_structure) do
154
- load './path1/class_a.rb'
136
+ it "should create a dot file" do
137
+ with_files(sample_dir_structure) do
138
+ run("./path1/class_a.rb")
139
+ run("#{File.dirname(__FILE__)}/../bin/rubydeps")
155
140
 
156
- dependencies, _ = ::Rubydeps.dependency_hash_for(:class_name_filter => /C|A/) do
157
- A.new.depend_on_b_and_c
141
+ File.read("rubydeps.dot").should match("digraph G")
158
142
  end
143
+ end
159
144
 
160
- dependencies.should == {"C"=>["A"]}
145
+ it "should be a correct test file" do
146
+ with_files(sample_dir_structure) do
147
+ status = run("./path1/class_a.rb")
148
+ status.should be_true
149
+ end
161
150
  end
162
- end
163
151
 
164
- it "should be capable of dumping the whole dependency data into a file for later filtering" do
165
- with_files(sample_dir_structure) do
166
- load './path1/class_a.rb'
152
+ it "should not filter classes when no filter is specified" do
153
+ with_files(sample_dir_structure) do
154
+ run("./path1/class_a.rb")
167
155
 
168
- ::Rubydeps.analyze(:to_file => 'dependencies.file') do
169
- A.new.depend_on_b_and_c
156
+ dependencies, _ = ::Rubydeps.dependency_hash_for(:from_file => 'rubydeps.dump')
157
+ dependencies.should == {"B"=>["A"], "C"=>["A"]}
170
158
  end
171
-
172
- dependencies, _ = ::Rubydeps.dependency_hash_for(:from_file => 'dependencies.file', :class_name_filter => /C|A/)
173
- dependencies.should == {"C"=>["A"]}
174
159
  end
175
- end
176
160
 
177
- it "should create correct dependencies for 2 instance methods called in a row" do
178
- dependencies, _ = ::Rubydeps.dependency_hash_for do
179
- Son.new.instance_method_calling_another_instance_method(Parent.new)
161
+ it "should filter classes when a path filter is specified" do
162
+ with_files(sample_dir_structure) do
163
+ run("./path1/class_a.rb")
164
+
165
+ dependencies, _ = ::Rubydeps.dependency_hash_for(:from_file => 'rubydeps.dump', :path_filter => /path1/)
166
+ dependencies.should == {"B"=>["A"]}
167
+ end
180
168
  end
181
169
 
182
- dependencies.should == {"Parent"=>["Son"]}
170
+ it "should filter classes when a class name filter is specified" do
171
+ with_files(sample_dir_structure) do
172
+ run("./path1/class_a.rb")
173
+
174
+ dependencies, _ = ::Rubydeps.dependency_hash_for(:from_file => 'rubydeps.dump', :class_name_filter => /C|A/)
175
+ dependencies.should == {"C"=>["A"]}
176
+ end
177
+ end
183
178
  end
184
179
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rubydeps
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 0.9.1.pre
5
+ version: 0.9.2.pre
6
6
  platform: ruby
7
7
  authors:
8
8
  - Daniel Cadenas
@@ -99,7 +99,6 @@ files:
99
99
  - bin/rubydeps
100
100
  - ext/call_site_analyzer/call_site_analyzer.c
101
101
  - ext/call_site_analyzer/extconf.rb
102
- - lib/call_site_analyzer.bundle
103
102
  - lib/rubydeps.rb
104
103
  - rake-deps.png
105
104
  - rubydeps.gemspec
Binary file