snuffle 0.13.0 → 0.14.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a1b604dec6afc7cf79045077c72b20027e6671b
4
- data.tar.gz: 435b312222a5e25db5a34bb9d07e008b31c806f7
3
+ metadata.gz: be82187f6d2b734240dd36555ab530cfbfe6e4be
4
+ data.tar.gz: eb57d17b6d4aba3c8114e55169b60b099715254a
5
5
  SHA512:
6
- metadata.gz: c41a7dc5273f10e51e33da5ad1fc56e8004cb480e38dca2d2fbc0af0fd3b0513ed8d1a0e6520674969c525b28a8d4e1360954aba66e09cc9b135142ed11e3a60
7
- data.tar.gz: c71957bf19e0c78af28d374b4f46253594ef3782fdc67f8910965fdaaf2d4dad739ea1945952fc40c843fb2bed6a82fefe55efaec25f37efe057da922f3b7c51
6
+ metadata.gz: 80457fff5e73a70dfbf62ce6fd3b7ae86f4076dfe1abc103f6b4f6be3f0623357063d13e2419861be4a4ab37ea958e93d8907e9a083c67997a6d0f301e35bb4d
7
+ data.tar.gz: aa36f7fc893adbf5c098fbea48226ce33947d074159a2a8751fb4ffd9c2565e1a94f21a77de8d11c7c9ab27e78daa7bfc7ef8d4f87580a178e9a7d23e734bcc4
@@ -12,6 +12,7 @@ require_relative "snuffle/formatters/csv"
12
12
  require_relative "snuffle/formatters/html"
13
13
  require_relative "snuffle/formatters/html_index"
14
14
  require_relative "snuffle/formatters/text"
15
+ require_relative "snuffle/args_clump"
15
16
  require_relative "snuffle/latent_object"
16
17
  require_relative "snuffle/line_of_code"
17
18
  require_relative "snuffle/node"
@@ -0,0 +1,46 @@
1
+ require 'pry'
2
+ module Snuffle
3
+
4
+ class ArgsClump
5
+
6
+ include PoroPlus
7
+ attr_accessor :element, :neighbors, :line_numbers
8
+
9
+ def self.from(nodes)
10
+ nodes = nodes.method_defs
11
+ clumps = Element::MethodDefinition.materialize(nodes.to_a).inject([]) do |clumps, element|
12
+ clump = ArgsClump.new(element: element, line_numbers: element.node.line_numbers.first )
13
+ if clump.values.count > 1 && clump.near_neighbors.any?
14
+ clumps << clump
15
+ end
16
+ clumps
17
+ end
18
+ end
19
+
20
+ def has_near_neighbors?
21
+ near_neighbors.present?
22
+ end
23
+
24
+ def near_neighbors
25
+ @near_neighbors ||= neighbors.select{ |n| (n.values & values).size > 0 }
26
+ end
27
+
28
+ def neighbors
29
+ @neighbors ||= [element.node.siblings - [self.element.node]].flatten.map{|sibling| Element::MethodDefinition.materialize([sibling]).first}
30
+ end
31
+
32
+ def values
33
+ @values ||= self.element.values
34
+ end
35
+
36
+ def neighbor
37
+ Struct.new(:element, :distance)
38
+ end
39
+
40
+ def distance(primary_matrix, token_matrix)
41
+ Snuffle::Util::Correlation.distance(primary_matrix, token_matrix)
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -36,7 +36,6 @@ module Snuffle
36
36
  def report(summary, source)
37
37
  text_report(summary)
38
38
  cvs_report(summary)
39
-
40
39
  end
41
40
 
42
41
  def create_html_index(summaries, start_path)
@@ -14,4 +14,14 @@ class Snuffle::Element::MethodDefinition
14
14
  node.name
15
15
  end
16
16
 
17
+ def values
18
+ begin
19
+ return [] unless node.children.objects.any?
20
+ node.children.objects[1].children.map{|child| child.name}.flatten
21
+ rescue
22
+ []
23
+ end
24
+ end
25
+
26
+
17
27
  end
@@ -39,8 +39,7 @@ module Snuffle
39
39
  end
40
40
 
41
41
  def filename
42
- base = "#{summary.filename}"
43
- base + file_extension
42
+ "#{summary.filename}" + file_extension
44
43
  end
45
44
 
46
45
  def file_extension
@@ -74,7 +74,7 @@
74
74
  %div.column
75
75
  %h3.indented.highlighted
76
76
  Data Clumps:
77
- - if summary.cohorts.count == 0
77
+ - unless summary.cohorts.any? || summary.arg_clumps.any?
78
78
  %p.indented
79
79
  %em None
80
80
  - else
@@ -87,6 +87,14 @@
87
87
  (line
88
88
  = ":#{cohorts.map(&:line_numbers).join(', :')}"
89
89
  )
90
+ - summary.arg_clumps.group_by{|c| c.values.sort }.each do |args, clumps|
91
+ - if clumps.count > 0
92
+ %li
93
+ = args.map{|c| ".#{c}" }.join(", ")
94
+ %br
95
+ (line
96
+ = ":#{clumps.map(&:line_numbers).join(', :')}"
97
+ )
90
98
  %div.column
91
99
  %h3.indented.highlighted-method
92
100
  Possible Latent Objects:
@@ -28,13 +28,13 @@ class Snuffle::LatentObject
28
28
  end
29
29
 
30
30
  def self.potential_objects_with_methods(nodes, threshold=DUPLICATE_THRESHOLD)
31
- method_candidates = Snuffle::Element::MethodDefinition.materialize(nodes.methods)
31
+ method_candidates = Snuffle::Element::MethodDefinition.materialize(nodes.method_defs)
32
32
  extract_candidates(method_candidates).select{|k,v| v.count > threshold }
33
33
  end
34
34
 
35
- def self.extract_candidates(methods)
35
+ def self.extract_candidates(method_defs)
36
36
  stemmer = UEAStemmer.new
37
- methods.map(&:method_name).inject({}) do |words, method_name|
37
+ method_defs.map(&:method_name).inject({}) do |words, method_name|
38
38
  atoms = method_name.split('_') - STOPWORDS
39
39
  atoms = atoms.map{|atom| stemmer.stem(atom.to_s)}
40
40
  atoms.each{ |word| words[word] ||= []; words[word] << method_name }
@@ -5,13 +5,12 @@ module Snuffle
5
5
  include Ephemeral::Base
6
6
  include PoroPlus
7
7
 
8
- attr_accessor :id, :name, :type, :child_ids, :parent_id, :line_numbers
8
+ attr_accessor :id, :name, :type, :child_ids, :parent_id, :line_numbers, :args
9
9
 
10
- scope :by_id, lambda{|id| where(:id => id)}
11
10
  scope :by_type, lambda{|type| where(:type => type)}
12
11
  scope :with_parent, lambda{|parent_id| where(parent_id: parent_id) }
13
12
  scope :hashes, {type: :hash}
14
- scope :methods, {is_method: true}
13
+ scope :method_defs, {is_method: true}
15
14
  scope :non_sends, {is_send: false}
16
15
 
17
16
  def self.nil
@@ -19,6 +19,10 @@ module Snuffle
19
19
  @nodes ||= extract_nodes_from(ast)
20
20
  end
21
21
 
22
+ def arg_clumps
23
+ @arg_clumps ||= ArgsClump.from(self.nodes)
24
+ end
25
+
22
26
  def cohorts
23
27
  @cohorts ||= Cohort.from(self.nodes)
24
28
  end
@@ -47,6 +51,7 @@ module Snuffle
47
51
  path_to_file: self.path_to_file,
48
52
  cohorts: cohorts,
49
53
  latent_objects: latent_objects,
54
+ arg_clumps: arg_clumps,
50
55
  source: self.source
51
56
  )
52
57
  end
@@ -3,9 +3,10 @@ module Snuffle
3
3
  class Summary
4
4
  include PoroPlus
5
5
  attr_accessor :class_name, :path_to_file, :cohorts, :latent_objects, :source
6
+ attr_accessor :arg_clumps
6
7
 
7
8
  def has_results?
8
- self.cohorts.count != 0 || self.latent_objects.count != 0
9
+ self.cohorts.count != 0 || self.latent_objects.count != 0 || self.arg_clumps.count != 0
9
10
  end
10
11
 
11
12
  def path_to_results
@@ -1,3 +1,3 @@
1
1
  module Snuffle
2
- VERSION = "0.13.0"
2
+ VERSION = "0.14.0"
3
3
  end
@@ -2,51 +2,41 @@ class Customer
2
2
 
3
3
  attr_accessor :customer_id, :customer_name, :company_name
4
4
  attr_accessor :street_address_1, :street_address_2
5
- # attr_accessor :city, :state, :postal_code
5
+ attr_accessor :city, :state, :postal_code, :phone_number
6
6
 
7
7
  MY_CONSTANT = "TheOtherZachIsThePrimaryZach"
8
8
 
9
9
  def self.api_root
10
- end
11
-
12
- def my_condition
13
- puts "MAGIC" if true == false
10
+ "http://localhost/api/"
14
11
  end
15
12
 
16
13
  def address_is_residence?
17
14
  self.company_name.nil?
18
15
  end
19
16
 
20
- def get_coords_for_address
21
- # fake_api_call(city: city, state: state, postal_code: postal_code)
22
- end
23
-
24
17
  def neighborhood
25
- make_neighborhood_api_call(state: self.state, city: self.city, postal_code: self.postal_code)
26
- end
27
-
28
- def something_else
29
- # fake_neighborhood_api_call(city: self.city, state: self.state)
18
+ NeighborhoodApi.post(
19
+ state: self.state,
20
+ city: self.city,
21
+ postal_code: self.postal_code
22
+ ).results[:neighborhood]
30
23
  end
31
24
 
32
- def and_something_else_again
33
- fake_neighborhood_api_call(city: self.city)
25
+ def verified_state
26
+ NeighborhoodApi.post(
27
+ city: self.city,
28
+ postal_code: self.postal_code
29
+ ).results[:state]
34
30
  end
35
31
 
36
- def and_something_else_again_and_again
37
- fake_neighborhood_api_call(state: self.state)
38
- end
39
-
40
- def fake_neighborhood_api_call(args={})
41
- "Probably River North"
42
- end
43
-
44
- def fake_api_call(args={})
45
- [112.32, 124.11]
32
+ def verified_country
33
+ NeighborhoodApi.post(
34
+ state: self.state,
35
+ ).results[:country]
46
36
  end
47
37
 
48
38
  def business_card_api_call
49
- {name: customer_name, business: company_name}
39
+ {name: customer_name, business: company_name, phone: phone_number}
50
40
  end
51
41
 
52
42
  def letterhead_api_call
@@ -63,7 +53,7 @@ class Customer
63
53
  string << self.company_name if address_is_residence?
64
54
  string << self.street_address_1
65
55
  string << self.street_address_2 if street_address_2.present?
66
- # string << "#{self.city}, #{self.state} #{self.postal_code}"
56
+ string << "#{self.city}, #{self.state} #{self.postal_code}"
67
57
  string.join", "
68
58
  end
69
59
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snuffle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Coraline Ada Ehmke
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-21 00:00:00.000000000 Z
12
+ date: 2015-04-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parser
@@ -213,6 +213,7 @@ files:
213
213
  - images/detail.png
214
214
  - images/overview.png
215
215
  - lib/snuffle.rb
216
+ - lib/snuffle/args_clump.rb
216
217
  - lib/snuffle/cli.rb
217
218
  - lib/snuffle/cohort.rb
218
219
  - lib/snuffle/elements/hash.rb
@@ -266,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
266
267
  version: '0'
267
268
  requirements: []
268
269
  rubyforge_project:
269
- rubygems_version: 2.2.2
270
+ rubygems_version: 2.4.6
270
271
  signing_key:
271
272
  specification_version: 4
272
273
  summary: Snuffle detects data clumps in your Ruby code.
@@ -284,3 +285,4 @@ test_files:
284
285
  - spec/snuffle/source_file_spec.rb
285
286
  - spec/snuffle/util/histogram_spec.rb
286
287
  - spec/spec_helper.rb
288
+ has_rdoc: