doppelganger 0.8.0

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.
@@ -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