Skip to content

Commit 777fb0d

Browse files
committed
Refactors analyzer to return sorted hash and implements reporter
1 parent dd9317e commit 777fb0d

File tree

6 files changed

+81
-84
lines changed

6 files changed

+81
-84
lines changed

lib/csscss.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
require "stringio"
2+
13
require "parslet"
24
require "csspool"
35

46
require "csscss/version"
57
require "csscss/types"
68
require "csscss/redundancy_analyzer"
9+
require "csscss/reporter"
710

811
module Csscss
9-
# Your code goes here...
1012
end

lib/csscss/redundancy_analyzer.rb

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,38 @@ def initialize(raw_css)
77

88
def redundancies(minimum = nil)
99
rule_sets = CSSPool.CSS(@raw_css).rule_sets
10-
{}.tap do |matches|
11-
used = {}
12-
rule_sets.each {|rs| downcase_all_expressions(rs) }
13-
rule_sets[0..-2].each.with_index do |rule_set1, index|
14-
rule_sets[(index + 1)..-1].each do |rule_set2|
15-
rule_set1.declarations.each do |dec|
16-
unless used[[rule_set1, dec]]
17-
if rule_set2.declarations.include?(dec)
18-
sel1 = Selector.new(rule_set1.selectors.map(&:to_s))
19-
sel2 = Selector.new(rule_set2.selectors.map(&:to_s))
20-
dec_key = Declaration.from_csspool(dec)
21-
matches[sel1] ||= {}
22-
matches[sel1][dec_key] ||= []
23-
matches[sel1][dec_key] << sel2
24-
used[[rule_set2,dec]] = true
25-
end
26-
end
27-
end
10+
matches = {}
11+
rule_sets.each do |rule_set|
12+
rule_set.declarations.each do |dec|
13+
dec.property.downcase!
14+
dec.expressions do |exp|
15+
exp.value.downcase!
2816
end
17+
18+
dec_key = Declaration.from_csspool(dec)
19+
sel = Selector.new(rule_set.selectors.map(&:to_s))
20+
matches[dec_key] ||= []
21+
matches[dec_key] << sel
2922
end
23+
end
3024

31-
if minimum
32-
matches.each do |rs1, dec_map|
33-
dec_map.each do |dec, other_rule_sets|
34-
dec_map.delete(dec) if other_rule_sets.size < minimum - 1
35-
end
25+
inverted_matches = {}
26+
matches.each do |declaration, selector_groups|
27+
inverted_matches[selector_groups] ||= []
28+
inverted_matches[selector_groups] << declaration
29+
end
3630

37-
matches.delete(rs1) if dec_map.keys.size == 0
38-
end
31+
if minimum
32+
inverted_matches.delete_if do |_, declarations|
33+
declarations.size < minimum
3934
end
4035
end
41-
end
4236

43-
private
44-
def downcase_all_expressions(rule_set)
45-
rule_set.declarations.each {|dec| dec.property.downcase! }
37+
sorted_array = inverted_matches.sort {|(_, v1), (_, v2)| v2.size <=> v1.size }
38+
{}.tap do |sorted_hash|
39+
sorted_array.each do |key, value|
40+
sorted_hash[key] = value
41+
end
42+
end
4643
end
4744
end

lib/csscss/reporter.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Csscss::Reporter
2+
def initialize(redundancies)
3+
@redundancies = redundancies
4+
end
5+
6+
def report
7+
io = StringIO.new
8+
@redundancies.each do |selector_groups, declarations|
9+
selector_groups = selector_groups.map {|selectors| "{#{selectors.selectors.join(", ")}}" }
10+
last_selector = selector_groups.pop
11+
count = declarations.size
12+
unless selector_groups.empty?
13+
io.puts %Q(#{selector_groups.join(", ")} and #{last_selector} share #{count} rule#{"s" if count > 1})
14+
end
15+
end
16+
17+
io.rewind
18+
io.read
19+
end
20+
end

spec/csscss/redundancy_analyzer_spec.rb

Lines changed: 0 additions & 41 deletions
This file was deleted.

test/csscss/redundancy_analyzer_test.rb

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@ module Csscss
66
css = %$
77
h1, h2 { display: none; position: relative; outline:none}
88
.foo { display: none; width: 1px }
9-
.bar { position: relative; width: 1px }
9+
.bar { position: relative; width: 1px; outline: none }
1010
.baz { display: none }
1111
$
1212

1313
RedundancyAnalyzer.new(css).redundancies.must_equal({
14-
sel(%w(h1 h2)) => {
15-
dec("display", "none") => [sel(".foo"), sel(".baz")],
16-
dec("position", "relative") => [sel(".bar")]
17-
},
18-
sel(".foo") => { dec("width", "1px") => [sel(".bar")] },
14+
[sel(%w(h1 h2)), sel(".bar")] => [dec("position", "relative"), dec("outline", "none")],
15+
[sel(%w(h1 h2)), sel(".foo"), sel(".baz")] => [dec("display", "none")],
16+
[sel(".foo"), sel(".bar")] => [dec("width", "1px")]
1917
})
2018

21-
RedundancyAnalyzer.new(css).redundancies(3).must_equal({
22-
sel(%w(h1 h2)) => {
23-
dec("display", "none") => [sel(".foo"), sel(".baz")]
24-
}
19+
RedundancyAnalyzer.new(css).redundancies.first.must_equal [
20+
[sel(%w(h1 h2)), sel(".bar")], [dec("position", "relative"), dec("outline", "none")]
21+
]
22+
23+
RedundancyAnalyzer.new(css).redundancies(2).must_equal({
24+
[sel(%w(h1 h2)), sel(".bar")] => [dec("position", "relative"),dec("outline", "none")]
2525
})
2626
end
2727

@@ -32,9 +32,7 @@ module Csscss
3232
$
3333

3434
RedundancyAnalyzer.new(css).redundancies.must_equal({
35-
sel(".foo") => {
36-
dec("width", "1px") => [sel(".bar")]
37-
}
35+
[sel(".foo"), sel(".bar")] => [dec("width", "1px")]
3836
})
3937
end
4038
end

test/csscss/reporter_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require "test_helper"
2+
3+
module Csscss
4+
describe Reporter do
5+
it "formats string result" do
6+
reporter = Reporter.new({
7+
[sel(".foo"), sel(".bar")] => [dec("width", "1px"), dec("border", "black")],
8+
[sel(%w(h1 h2)), sel(".foo"), sel(".baz")] => [dec("display", "none")],
9+
[sel(%w(h1 h2)), sel(".bar")] => [dec("position", "relative")],
10+
[sel(%w(h1 h2))] => [dec("outline", "none")]
11+
})
12+
13+
expected =<<-EXPECTED
14+
{.foo} and {.bar} share 2 rules
15+
{h1, h2}, {.foo} and {.baz} share 1 rule
16+
{h1, h2} and {.bar} share 1 rule
17+
EXPECTED
18+
reporter.report.must_equal expected
19+
end
20+
end
21+
end

0 commit comments

Comments
 (0)