Commit df97977f authored by Coraline Ehmke's avatar Coraline Ehmke

Output latent objects

parent 6fbb3cee
......@@ -49,13 +49,13 @@ module Snuffle
def cvs_report(summary)
return unless options['format'] == 'csv'
return unless summary.cohorts.count > 0
return unless summary.cohorts.count > 0 || summary.latent_objects.count > 0
results_files << Snuffle::Formatters::Csv.new(summary).export
end
def html_report(summary, source)
return unless options['format'] == 'html'
return unless summary.cohorts.count > 0
return unless summary.cohorts.count > 0 || summary.latent_objects.count > 0
results_files << Snuffle::Formatters::Html.new(summary, source).export
end
......
......@@ -71,7 +71,7 @@
%br.clear
%div.file_listing.center
%div.summary.center
%em
Analyzed on
= date
......
......@@ -15,12 +15,14 @@
pre.lineno { margin-top: -1.4em !important;}
pre { line-height: 1.75em;}
span.highlighted { background: rgba(200, 0, 0, .4); padding-left: 1em; border-radius: 100px; display: inline-block; position: absolute; left: 0px; padding-right: 90%}
span.highlighted-method { background: rgba(249, 212, 36, .4); padding: .25em; border-radius: 100px;}
h1 { color:#fff; font-size: 1.25em; margin-top: .25em; }
h2 { color:#fff; font-size: .75em; margin-top: -1em; }
h3 { color:#fff; font-size: 1.1em;margin-top: 1em; }
li { margin-bottom: 1em;}
div.column { float: left; width: 45%; }
div.file_meta { padding: 1em; border-radius: 5px; background: #444; height: 3.5em; width: 98%; border: .5em solid #000;}
div.file_listing { padding: .5em; border-radius: 5px; background: #222; width: 100%; border: 1px solid #000;}
div.file_listing { padding: .5em; border-radius: 5px; background: #000; width: 100%; border: 1px solid #000;}
= ".summary {padding: 1em; border-radius: 5px; background: #4c5d62; width: 98%; border: .5em solid #000;}"
= ".clear { clear: both; }"
= ".indented {margin-left: 1em; }"
......@@ -36,16 +38,35 @@
%br.clear
%div.summary
%h3.indented
Candidate object attributes:
%ul.indented
- summary.cohorts.group_by{|c| c.values.sort }.each do |values, cohorts|
- if cohorts.count > 0
%li
= values.map{|c| "##{c}" }.join(", ")
%br
= ":#{cohorts.map(&:line_numbers).join(', :')}"
%div.column
%h3.indented
Data Clumps:
- if summary.cohorts.count == 0
%em.indented None
- else
%ul.indented
- summary.cohorts.group_by{|c| c.values.sort }.each do |values, cohorts|
- if cohorts.count > 0
%li
= values.map{|c| ".#{c}" }.join(", ")
%br
(from
= ":#{cohorts.map(&:line_numbers).join(', :')}"
)
%div.column
%h3.indented
Possible Latent Objects:
- if summary.latent_objects.count == 0
%em.indented None
- else
%ul.indented
- summary.latent_objects.each do |latent_object|
%li
= latent_object.object_candidate.titleize
%br
(from
= ".#{latent_object.source_methods.join(', .')}"
)
%br.clear
%br.clear
......@@ -59,10 +80,9 @@
:javascript
var line_numbers = #{summary.cohorts.map(&:line_numbers).flatten};
var method_names = #{summary.latent_objects.map(&:source_methods).flatten};
$('pre.lineno').html($('pre.lineno').html().split(/\s+/).map(function(val){ if (line_numbers.indexOf(parseInt(val)) > -1) { return "<span class='highlighted'>" + val + "</span>\n" } else { return "<span class='foo'>" + val + "</span>\n"};}))
for (i = 0; i <= line_numbers; i ++) {
$('.code pre').html($('.code pre').html().split(/\s+/)[i].html("<span class='highlighted'>" + i + "</span>\n"))
}
$('.nf').each(function(i, elem) { if (method_names.indexOf($(elem).text()) > -1) { $(elem).addClass('highlighted-method'); }})
......@@ -5,6 +5,18 @@ class Snuffle::LatentObject
attr_accessor :object_candidate, :source_methods
DUPLICATE_THRESHOLD = 1
STOPWORDS = [
"the", "be", "to", "of", "and", "a", "in", "that", "have", "I", "it", "for",
"not", "on", "with", "he", "as", "you", "do", "at", "this", "but", "his",
"by", "from", "they", "we", "say", "her", "she", "or", "an", "will", "my",
"one", "all", "would", "there", "their", "what", "so", "up", "out", "if",
"about", "who", "get", "which", "go", "me", "when", "make", "can", "like",
"time", "no", "just", "him", "know", "take", "into", "else", "other", "again",
"your", "good", "some", "could", "them", "see", "other", "than", "then",
"now", "look", "only", "come", "its", "over", "think", "also", "back", "else",
"after", "use", "two", "how", "our", "work", "first", "well", "way", "even",
"new", "want", "because", "any", "these", "give", "day", "most", "us", "call"
]
def self.from(nodes)
potential_objects_with_methods(nodes).map do |k,v|
......@@ -19,7 +31,7 @@ class Snuffle::LatentObject
def self.extract_candidates(methods)
methods.map(&:method_name).inject({}) do |words, method_name|
atoms = method_name.split('_')
atoms = method_name.split('_') - STOPWORDS
atoms.each{ |word| words[word] ||= []; words[word] << method_name }
words
end
......
......@@ -23,6 +23,10 @@ module Snuffle
@cohorts ||= Cohort.from(self.nodes)
end
def latent_objects
@latent_objects ||= LatentObject.from(self.nodes)
end
def source
return @source if @source
end_pos = 0
......@@ -42,6 +46,7 @@ module Snuffle
class_name: class_name,
path_to_file: self.path_to_file,
cohorts: cohorts,
latent_objects: latent_objects,
source: self.source
)
end
......@@ -98,7 +103,7 @@ module Snuffle
if name_coords = node.loc.name
name = source[name_coords.begin_pos, name_coords.end_pos - 1]
return unless name =~ /[a-zA-Z]/
return name.gsub(/^([A-Za-z0-9\_]+)(.+)$/m, '\1')
return name.gsub(/^([A-Za-z0-9\_\?\!]+)(.+)$/m, '\1')
end
else
return name_from(node.children.last)
......
......@@ -2,7 +2,7 @@ module Snuffle
class Summary
include PoroPlus
attr_accessor :class_name, :path_to_file, :cohorts, :source
attr_accessor :class_name, :path_to_file, :cohorts, :latent_objects, :source
def class_filename
self.class_name.downcase.gsub(' ', '_')
......
require "spec_helper"
Snuffle::Node.class_variable_set(:@@objects, [])
describe Snuffle::Node do
let(:source) { Snuffle::SourceFile.new }
......@@ -13,24 +15,4 @@ describe Snuffle::Node do
end
end
describe "#parent" do
it "returns a node's parent" do
allow(child_2).to receive(:id) { 3 }
expect(Snuffle::Node.by_id(3).first.parent).to eq parent
end
end
describe "#siblings" do
before do
allow(parent).to receive(:id) { 1 }
allow(child_1).to receive(:id) { 2 }
allow(child_2).to receive(:id) { 3 }
end
it "returns other nodes of a node's type" do
expect(Snuffle::Node.by_id(3).first.siblings).to eq [parent, child_1]
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment