doppelganger 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ def muir
2
+ puts "John Muir"
3
+ @variable = "muir"
4
+ %w(this is some words).each do |word|
5
+ word.size
6
+ end
7
+ end
@@ -0,0 +1,53 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class DoppelgangerSexpTest < Test::Unit::TestCase
4
+
5
+ context 'extended Sexp object' do
6
+ setup do
7
+ @pt = RubyParser.new
8
+ sample_file_path = File.expand_path(File.join(File.dirname(__FILE__), 'sample_files/sexp_test_file.rb'))
9
+ @sexp = @pt.process(File.read(sample_file_path), sample_file_path)
10
+ end
11
+
12
+ should 'remove all literal objects' do
13
+ clean_sexp_array = [:defn,
14
+ :muir,
15
+ [:args],
16
+ [:scope,
17
+ [:block,
18
+ [:call, :puts, [:arglist, [:str]]],
19
+ [:iasgn, :@variable, [:str]],
20
+ [:iter,
21
+ [:call,
22
+ [:array, [:str], [:str], [:str], [:str]],
23
+ :each,
24
+ [:arglist]],
25
+ [:lasgn, :word],
26
+ [:call, [:lvar, :word], :size, [:arglist]]]]]]
27
+ assert_equal clean_sexp_array, @sexp.remove_literals.to_a
28
+ end
29
+
30
+ should 'return flattened array' do
31
+ flat_array = [:defn, :muir, :args, :scope, :block, :call, nil, :puts, :arglist, :str,
32
+ "John Muir", :iasgn, :@variable, :str, "muir", :iter, :call, :array, :str,
33
+ "this", :str, "is", :str, "some", :str, "words", :each, :arglist, :lasgn,
34
+ :word, :call, :lvar, :word, :size, :arglist]
35
+ assert_equal flat_array, @sexp.to_flat_ary
36
+ end
37
+
38
+ should 'retrive last line number for a given node' do
39
+ assert_respond_to @sexp, :last_line_number
40
+ assert_equal 6, @sexp.last_line_number
41
+ end
42
+
43
+ should 'determin if a block Sexp node is a child of another node' do
44
+ block_node = @sexp[3][1]
45
+ assert @sexp.contains_block?(block_node)
46
+ end
47
+
48
+ teardown do
49
+ @pt, @sexp = nil
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,79 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+ require File.expand_path( File.join(File.dirname(__FILE__), %w[.. lib doppelganger]) )
5
+
6
+
7
+ class DoppelgangerTestCase < Test::Unit::TestCase
8
+ def setup
9
+ @the_nodes = [
10
+ # second_file.rb
11
+ [:defn, :foo, [:args], [:scope, [:block, [:return, [:str, "also not unique"]]]]],
12
+ [:defn, :baz, [:args], [:scope, [:block, [:or, [:true], [:str, "is unique"]]]]],
13
+
14
+ # first_file.rb
15
+ [:defn, :foo, [:args], [:scope, [:block, [:call, nil, :puts, [:arglist, [:lit, :something_unique]]]]]],
16
+ [:defn, :bar, [:args], [:scope, [:block, [:return, [:str, "something not unique"]]]]]
17
+ ]
18
+
19
+ @bigger_diff_blocks = [
20
+ [:defn, :foo, [:args],
21
+ [:scope,
22
+ [:block,
23
+ [:call, nil, :puts,
24
+ [:arglist, [:str, "muppetfuckers"]]],
25
+ [:iasgn, :@variable, [:str, "foo"]],
26
+ [:iter, [:call,
27
+ [:array, [:str, "this"], [:str, "is"], [:str, "some"], [:str, "words"]], :each, [:arglist]],
28
+ [:lasgn, :word],
29
+ [:call, [:lvar, :word], :size, [:arglist]]]]]],
30
+ [:defn, :bar, [:args],
31
+ [:scope, [:block,
32
+ [:call, nil, :puts,
33
+ [:arglist, [:str, "muppetfuckers"]]],
34
+ [:iter, [:call,
35
+ [:array, [:str, "this"], [:str, "is"], [:str, "bad"], [:str, "words"]], :each, [:arglist]],
36
+ [:lasgn, :word],
37
+ [:call, nil, :puts, [:arglist, [:lvar, :word]]]],
38
+ [:iasgn, :@variable, [:str, "bar"]]]]]
39
+ ]
40
+
41
+ @repeated_pairs = [
42
+ [s(:block, s(:iter, s(:call, s(:self), :each_sexp, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:call, s(:lvar, :block), :[], s(:arglist, s(:lvar, :sexp))), s(:call, s(:lvar, :sexp), :deep_each, s(:arglist, s(:block_pass, s(:lvar, :block))))))),
43
+ s(:defn, :deep_each, s(:args, :"&block"), s(:scope, s(:block, s(:iter, s(:call, s(:self), :each_sexp, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:call, s(:lvar, :block), :[], s(:arglist, s(:lvar, :sexp))), s(:call, s(:lvar, :sexp), :deep_each, s(:arglist, s(:block_pass, s(:lvar, :block)))))))))],
44
+
45
+ [s(:block, s(:lasgn, :line_number, s(:nil)), s(:iter, s(:call, s(:self), :deep_each, s(:arglist)), s(:lasgn, :sub_node), s(:if, s(:call, s(:lvar, :sub_node), :respond_to?, s(:arglist, s(:lit, :line))), s(:lasgn, :line_number, s(:call, s(:lvar, :sub_node), :line, s(:arglist))), nil)), s(:lvar, :line_number)),
46
+ s(:defn, :last_line_number, s(:args), s(:scope, s(:block, s(:lasgn, :line_number, s(:nil)), s(:iter, s(:call, s(:self), :deep_each, s(:arglist)), s(:lasgn, :sub_node), s(:if, s(:call, s(:lvar, :sub_node), :respond_to?, s(:arglist, s(:lit, :line))), s(:lasgn, :line_number, s(:call, s(:lvar, :sub_node), :line, s(:arglist))), nil)), s(:lvar, :line_number))))],
47
+
48
+ [s(:block, s(:iter, s(:call, s(:self), :inject, s(:arglist, s(:call, nil, :s, s(:arglist)))), s(:masgn, s(:array, s(:lasgn, :sexps), s(:lasgn, :sexp))), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), s(:call, s(:lvar, :sexps), :<<, s(:arglist, s(:yield, s(:lvar, :sexp)))), s(:call, s(:lvar, :sexps), :<<, s(:arglist, s(:lvar, :sexp)))), s(:lvar, :sexps)))),
49
+ s(:defn, :map_sexps, s(:args), s(:scope, s(:block, s(:iter, s(:call, s(:self), :inject, s(:arglist, s(:call, nil, :s, s(:arglist)))), s(:masgn, s(:array, s(:lasgn, :sexps), s(:lasgn, :sexp))), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), s(:call, s(:lvar, :sexps), :<<, s(:arglist, s(:yield, s(:lvar, :sexp)))), s(:call, s(:lvar, :sexps), :<<, s(:arglist, s(:lvar, :sexp)))), s(:lvar, :sexps))))))],
50
+
51
+ [s(:block, s(:lasgn, :output_sexp, s(:iter, s(:call, s(:self), :reject, s(:arglist)), s(:lasgn, :node), s(:call, s(:lvar, :block), :[], s(:arglist, s(:lvar, :node))))), s(:iter, s(:call, s(:lvar, :output_sexp), :map_sexps, s(:arglist)), s(:lasgn, :sexp), s(:call, s(:lvar, :sexp), :deep_reject, s(:arglist, s(:block_pass, s(:lvar, :block)))))),
52
+ s(:defn, :deep_reject, s(:args, :"&block"), s(:scope, s(:block, s(:lasgn, :output_sexp, s(:iter, s(:call, s(:self), :reject, s(:arglist)), s(:lasgn, :node), s(:call, s(:lvar, :block), :[], s(:arglist, s(:lvar, :node))))), s(:iter, s(:call, s(:lvar, :output_sexp), :map_sexps, s(:arglist)), s(:lasgn, :sexp), s(:call, s(:lvar, :sexp), :deep_reject, s(:arglist, s(:block_pass, s(:lvar, :block))))))))],
53
+
54
+ [s(:block, s(:lasgn, :output, s(:call, s(:self), :dup, s(:arglist))), s(:iter, s(:call, s(:lvar, :output), :deep_reject, s(:arglist)), s(:lasgn, :node), s(:not, s(:or, s(:call, s(:lvar, :node), :is_a?, s(:arglist, s(:const, :Symbol))), s(:call, s(:lvar, :node), :is_a?, s(:arglist, s(:const, :Sexp))))))),
55
+ s(:defn, :remove_literals, s(:args), s(:scope, s(:block, s(:lasgn, :output, s(:call, s(:self), :dup, s(:arglist))), s(:iter, s(:call, s(:lvar, :output), :deep_reject, s(:arglist)), s(:lasgn, :node), s(:not, s(:or, s(:call, s(:lvar, :node), :is_a?, s(:arglist, s(:const, :Symbol))), s(:call, s(:lvar, :node), :is_a?, s(:arglist, s(:const, :Sexp)))))))))],
56
+
57
+ [s(:block, s(:iter, s(:call, s(:self), :each, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp))))),
58
+ s(:defn, :each_sexp, s(:args), s(:scope, s(:block, s(:iter, s(:call, s(:self), :each, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp)))))))],
59
+
60
+ [s(:block, s(:iter, s(:call, s(:self), :each, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp))))),
61
+ s(:block, s(:iter, s(:call, s(:self), :any?, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp)))))],
62
+
63
+ [s(:block, s(:iter, s(:call, s(:self), :each, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp))))),
64
+ s(:defn, :any_sexp?, s(:args), s(:scope, s(:block, s(:iter, s(:call, s(:self), :any?, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp)))))))],
65
+
66
+ [s(:defn, :each_sexp, s(:args), s(:scope, s(:block, s(:iter, s(:call, s(:self), :each, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp))))))),
67
+ s(:block, s(:iter, s(:call, s(:self), :any?, s(:arglist)), s(:lasgn, :sexp), s(:block, s(:if, s(:call, s(:const, :Sexp), :===, s(:arglist, s(:lvar, :sexp))), nil, s(:next)), s(:yield, s(:lvar, :sexp)))))]
68
+ ]
69
+
70
+ @analyzer = Doppelganger::Extractor.new
71
+ end
72
+
73
+ def default_test; end
74
+
75
+ def teardown
76
+ @the_nodes, @unique_block, @bigger_diff_blocks, @anlyzer, @repeated_pairs = nil
77
+ end
78
+ end
79
+
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: doppelganger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.0
5
+ platform: ruby
6
+ authors:
7
+ - Brian Landau
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-18 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sexp_processor
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: ruby_parser
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: ruby2ruby
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.2.0
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: diff-lcs
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: "1.1"
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: highline
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: "1.4"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: facets
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ version: "2.4"
74
+ version:
75
+ - !ruby/object:Gem::Dependency
76
+ name: thoughtbot-shoulda
77
+ type: :development
78
+ version_requirement:
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: "2.0"
84
+ version:
85
+ description: Doppelganger helps you to find areas of your code that are good places to refactor. It does this by finding methods and blocks that are duplicates or have less then a set threshold level of difference or be less then a specified percent different. This library can either be used with in another larger code metric/heuristic library, or called from the command line.
86
+ email: brian.landau@viget.com
87
+ executables:
88
+ - doppelganger
89
+ extensions: []
90
+
91
+ extra_rdoc_files:
92
+ - CHANGELOG
93
+ - LICENSE
94
+ - README.rdoc
95
+ files:
96
+ - CHANGELOG
97
+ - LICENSE
98
+ - Manifest.txt
99
+ - README.rdoc
100
+ - Rakefile
101
+ - bin/doppelganger
102
+ - doppelganger.gemspec
103
+ - lib/doppelganger.rb
104
+ - lib/doppelganger/extractor.rb
105
+ - lib/doppelganger/exts/array.rb
106
+ - lib/doppelganger/exts/sexp.rb
107
+ - lib/doppelganger/node_analysis.rb
108
+ - lib/doppelganger/unified_ruby.rb
109
+ - tasks/bones.rake
110
+ - tasks/gem.rake
111
+ - tasks/git.rake
112
+ - tasks/manifest.rake
113
+ - tasks/post_load.rake
114
+ - tasks/rdoc.rake
115
+ - tasks/rubyforge.rake
116
+ - tasks/setup.rb
117
+ - tasks/test.rake
118
+ - test/array_test.rb
119
+ - test/doppelganger_test.rb
120
+ - test/sample_files/duplicate_test_data/first_file.rb
121
+ - test/sample_files/duplicate_test_data/second_file.rb
122
+ - test/sample_files/larger_diff/first_file.rb
123
+ - test/sample_files/larger_diff/second_file.rb
124
+ - test/sample_files/repeats_removal_sample_file.rb
125
+ - test/sample_files/sexp_test_file.rb
126
+ - test/sexp_ext_test.rb
127
+ - test/test_helper.rb
128
+ has_rdoc: true
129
+ homepage: http://doppelganger.rubyforge.org/
130
+ post_install_message:
131
+ rdoc_options:
132
+ - --main
133
+ - README.rdoc
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: "0"
141
+ version:
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: "0"
147
+ version:
148
+ requirements: []
149
+
150
+ rubyforge_project: doppelganger
151
+ rubygems_version: 1.3.1
152
+ signing_key:
153
+ specification_version: 2
154
+ summary: Doppelganger helps you to find areas of your code that are good places to refactor
155
+ test_files:
156
+ - test/array_test.rb
157
+ - test/doppelganger_test.rb
158
+ - test/sexp_ext_test.rb