duvet 0.3.3 → 0.4.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.
@@ -1,3 +1,3 @@
1
1
  module Duvet
2
- VERSION = '0.3.3'
3
- end
2
+ VERSION = '0.4.0'
3
+ end
@@ -0,0 +1,91 @@
1
+ require_relative '../helper'
2
+
3
+ describe Duvet::Cov do
4
+
5
+ let(:lines) { [5, 2, nil, 2, 4, 3, 0, 0, 0, nil] }
6
+ subject { Duvet::Cov.new('lib/duvet.rb', lines) }
7
+
8
+ describe '#path' do
9
+ it 'returns the cleaned path' do
10
+ cov = Duvet::Cov.new(Dir.pwd + '/test.rb', [])
11
+ cov.path.must_equal Pathname.new('test.rb')
12
+ end
13
+ end
14
+
15
+ describe '#lines' do
16
+ it 'returns the passed coverage data' do
17
+ subject.lines.must_equal lines
18
+ end
19
+ end
20
+
21
+ describe '#code_lines' do
22
+ it 'returns lines which can be exectued' do
23
+ subject.code_lines.must_equal [5, 2, 2, 4, 3, 0, 0, 0]
24
+ end
25
+ end
26
+
27
+ describe '#ran_lines' do
28
+ it 'returns lines which were executed' do
29
+ subject.ran_lines.must_equal [5, 2, 2, 4, 3]
30
+ end
31
+ end
32
+
33
+
34
+ describe '#total_coverage' do
35
+ it 'returns the ratio of lines which were executed' do
36
+ subject.total_coverage.must_equal 0.5
37
+ end
38
+ end
39
+
40
+ describe '#code_coverage' do
41
+ it 'returns the ratio of executable lines which were executed' do
42
+ subject.code_coverage.must_equal 0.625
43
+ end
44
+ end
45
+
46
+ describe '#percent' do
47
+ it 'returns a number as a 4-digit (ie. ??.??) percentage' do
48
+ subject.percent(0.123456789).must_equal "12.35%"
49
+ end
50
+ end
51
+
52
+ describe '#report' do
53
+ it 'generates a simple textual report of coverage' do
54
+ subject.report.must_equal <<EOS
55
+ lib/duvet.rb
56
+ total: 50.00%
57
+ code: 62.50%
58
+ EOS
59
+ end
60
+ end
61
+
62
+ describe '#data' do
63
+ it 'contains the necessary template data' do
64
+ subject.path.stubs(:readlines).returns("code and code and code")
65
+
66
+ subject.data.must_equal file: {
67
+ path: 'lib/duvet.rb',
68
+ url: 'lib/duvet.html',
69
+ root: '../',
70
+ source: 'code and code and code',
71
+ },
72
+ lines: {
73
+ total: 10,
74
+ code: 8,
75
+ ran: 5
76
+ },
77
+ coverage: {
78
+ code: '62.50%',
79
+ total: '50.00%',
80
+ lines: lines
81
+ }
82
+ end
83
+ end
84
+
85
+ describe '#write' do
86
+ it 'writes the file' do
87
+ Duvet.expects(:write).with(subject.data, 'html/file.erb')
88
+ subject.write
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,57 @@
1
+ require_relative '../helper'
2
+
3
+ describe Duvet::Covs do
4
+
5
+ let(:files) {
6
+ {
7
+ 'lib/duvet.rb' => [3, 2, 1, 0, nil],
8
+ 'lib/duvet/cov.rb' => [nil, nil, 0, 1, 2]
9
+ }
10
+ }
11
+
12
+ subject { Duvet::Covs.from_data files }
13
+
14
+ describe '.from_data' do
15
+ it 'converts data to Cov instances' do
16
+ subject.each do |cov|
17
+ cov.must_be_kind_of Duvet::Cov
18
+ end
19
+ end
20
+ end
21
+
22
+ describe '#report' do
23
+ it 'creates a report' do
24
+ subject.report.must_equal <<EOS
25
+ lib/duvet.rb
26
+ total: 60.00%
27
+ code: 75.00%
28
+
29
+ lib/duvet/cov.rb
30
+ total: 40.00%
31
+ code: 66.67%
32
+
33
+ EOS
34
+ end
35
+ end
36
+
37
+ describe '#data' do
38
+ it 'populates the data' do
39
+ subject.data.must_include :files
40
+ end
41
+ end
42
+
43
+ describe '#write' do
44
+ it 'writes the index and individual covs' do
45
+ subject.each {|i| i.expects(:write) }
46
+ Duvet.expects(:write).with(subject.data, 'html/index.erb')
47
+
48
+ subject.write
49
+ end
50
+
51
+ it 'warns if no coverage to write' do
52
+ empty = Duvet::Covs.new
53
+ -> { empty.write }.must_output nil, "No files to create coverage for.\n"
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,81 @@
1
+ require_relative 'helper'
2
+
3
+ describe Duvet do
4
+
5
+ before { Coverage.stubs(:start) }
6
+ subject { Duvet.dup }
7
+
8
+ describe '#start' do
9
+ it 'makes sure :filter is a regexp' do
10
+ subject.start :filter => 'str'
11
+ subject.opts[:filter].must_be_kind_of Regexp
12
+ end
13
+
14
+ it 'starts Coverage' do
15
+ Coverage.expects(:start)
16
+ subject.start
17
+ end
18
+ end
19
+
20
+ describe '#result' do
21
+ it 'filters the results' do
22
+ Coverage.expects(:result).returns({'a/b.c' => [], 'a/e.f' => [], 'g/h.i' => []})
23
+ subject.start :filter => 'a/e'
24
+
25
+ subject.result.map(&:path).map(&:to_s).must_equal ['a/e.f']
26
+ end
27
+
28
+ it 'returns a Covs instance' do
29
+ Coverage.stubs(:result).returns({'a/b.c' => []})
30
+ subject.result.must_be_kind_of Duvet::Covs
31
+ end
32
+ end
33
+
34
+ describe '#format' do
35
+ it 'renders a file from the data and template given' do
36
+ Pathname.any_instance.stubs(:read).returns("The magic number is <%= a %>")
37
+ r = subject.format({a: 1}, 'template.erb')
38
+ r.must_equal "The magic number is 1"
39
+ end
40
+ end
41
+
42
+ describe '#write' do
43
+ it 'formats then writes a file' do
44
+ formatted = Object.new
45
+ data = {file: {url: 'somewhere/file.html'}}
46
+ subject.expects(:format).with(data, 'template').returns(formatted)
47
+ subject.expects(:write_file).with(formatted, 'somewhere/file.html')
48
+
49
+ subject.write data, 'template'
50
+ end
51
+ end
52
+
53
+ describe '#write_file' do
54
+ it 'writes a file' do
55
+ File.expects(:open).with(Pathname.new('cov/somewhere/file.html'), 'w')
56
+ subject.write_file 'text', 'somewhere/file.html'
57
+ end
58
+ end
59
+
60
+ describe '#write_resources' do
61
+ it 'writes the resources' do
62
+ subject.stubs(:write_file)
63
+ 4.times { subject.expects(:write_file) }
64
+
65
+ subject.write_resources
66
+ end
67
+ end
68
+
69
+ describe '#finish' do
70
+ it 'makes the directory, writes the results and resources' do
71
+ FileUtils.expects(:mkdir_p).with(subject.opts[:dir])
72
+ obj = mock()
73
+ subject.expects(:result).returns(obj)
74
+ obj.expects(:write)
75
+ subject.expects(:write_resources)
76
+
77
+ subject.finish
78
+ end
79
+ end
80
+
81
+ end
@@ -7,13 +7,7 @@ Coverage.start
7
7
  require_relative '../lib/duvet'
8
8
  Duvet.start :filter => 'lib/duvet'
9
9
 
10
- require 'minitest/mock'
10
+ require 'minitest/autorun'
11
11
  require 'minitest/pride'
12
12
 
13
- require 'rr'
14
- class MiniTest::Unit::TestCase
15
- include RR::Adapters::TestUnit
16
- end
17
-
18
- MiniTest::Unit.autorun
19
-
13
+ require 'mocha'
@@ -0,0 +1,129 @@
1
+ @charset "UTF-8";
2
+ html {
3
+ margin: 0;
4
+ padding: 0;
5
+ width: 100%; }
6
+
7
+ body {
8
+ background: #f4f2ed;
9
+ font: 12px/1.3em Helvetica;
10
+ margin: 8px; }
11
+
12
+ a {
13
+ text-decoration: none; }
14
+
15
+ header {
16
+ margin: 2em 0.5em;
17
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); }
18
+ header h1, header h1 a {
19
+ color: #333333; }
20
+ header h2 {
21
+ color: #999999;
22
+ font-size: 16px; }
23
+
24
+ #filter {
25
+ position: absolute;
26
+ top: 20px;
27
+ right: 8px;
28
+ border: 1px solid #787878;
29
+ background: #f0f0f0;
30
+ -webkit-border-radius: 3px;
31
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1), 0 1px 0 white;
32
+ -webkit-transition: all 0.2s;
33
+ padding: 4px;
34
+ width: 180px; }
35
+ #filter:focus {
36
+ outline: none;
37
+ background: #f4f4f4;
38
+ border: 1px solid #646464; }
39
+
40
+ .table-wrapper {
41
+ min-width: 700px; }
42
+
43
+ table {
44
+ border: 1px solid grey;
45
+ background: #e0dedb;
46
+ border-collapse: collapse;
47
+ width: 100%;
48
+ margin-bottom: 1em;
49
+ -webkit-box-shadow: 0 1px 0 white; }
50
+
51
+ table.source, pre, code {
52
+ font: 11px/1.2em Menlo; }
53
+
54
+ td pre {
55
+ margin: 0; }
56
+
57
+ .summary {
58
+ margin-bottom: 1em;
59
+ background: #e0dedb; }
60
+ .summary tbody .name, .summary tbody .name a {
61
+ color: black;
62
+ font-weight: bold; }
63
+ .summary tbody tr:hover {
64
+ background: #c8c5c0; }
65
+ .summary thead {
66
+ background: #333333;
67
+ color: #cccccc; }
68
+ .summary thead th {
69
+ cursor: pointer; }
70
+ .summary tr {
71
+ text-align: left; }
72
+ .summary th, .summary td {
73
+ padding: 0.5em; }
74
+ .summary .header::after {
75
+ font-size: 10px;
76
+ margin-left: 10px; }
77
+ .summary .descending::after {
78
+ content: "▼"; }
79
+ .summary .ascending::after {
80
+ content: "▲"; }
81
+ .summary .lines, .summary .loc, .summary .ran, .summary .cov, .summary .code {
82
+ width: 100px; }
83
+
84
+ .totals {
85
+ border-top: 1px solid grey;
86
+ background: #c8c5c0;
87
+ font-weight: bold; }
88
+
89
+ .source tr pre {
90
+ margin-left: 3px; }
91
+ .source tr .count {
92
+ background: white;
93
+ -webkit-border-radius: 4px;
94
+ -webkit-border-top-left-radius: 0px;
95
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
96
+ border: 1px solid black;
97
+ display: block;
98
+ padding: 3px;
99
+ position: absolute;
100
+ margin-top: -1.3em;
101
+ right: 15px;
102
+ opacity: 0; }
103
+ .source tr .no {
104
+ color: #cccccc;
105
+ background: #333333;
106
+ padding: 0 0 0 3px;
107
+ width: 25px; }
108
+ .source tr:hover .count {
109
+ opacity: 1; }
110
+ .source tr:hover .no {
111
+ color: white; }
112
+ .source tr.excluded {
113
+ background: #e0dedb; }
114
+ .source tr.excluded:hover {
115
+ background: #c8c5c0; }
116
+ .source tr.unran {
117
+ background: #ce8b8c; }
118
+ .source tr.unran:hover {
119
+ background: #bf6768; }
120
+ .source tr.ran {
121
+ background: #bed2be; }
122
+ .source tr.ran:hover {
123
+ background: #a0bda0; }
124
+
125
+ footer {
126
+ color: rgba(0, 0, 0, 0.6);
127
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); }
128
+ footer a {
129
+ color: black; }
@@ -2,19 +2,19 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
- <title><%= file['path'] %></title>
6
- <link rel="stylesheet" href="styles.css" type="text/css" />
7
- <script type="text/javascript" src="jquery.js"></script>
8
- <script type="text/javascript" src="main.js"></script>
9
- <script type="text/javascript" src="plugins.js"></script>
5
+ <title><%= file.path %></title>
6
+ <link rel="stylesheet" href="<%= file.root %>styles.css" type="text/css" />
7
+ <script type="text/javascript" src="<%= file.root %>jquery.js"></script>
8
+ <script type="text/javascript" src="<%= file.root %>main.js"></script>
9
+ <script type="text/javascript" src="<%= file.root %>plugins.js"></script>
10
10
  </head>
11
-
11
+
12
12
  <body>
13
13
  <header>
14
- <h1><a href="index.html">Coverage</a></h1>
15
- <h2><%= file['path'] %></h2>
14
+ <h1><a href="<%= file.root %>index.html">Coverage</a></h1>
15
+ <h2><%= file.path %></h2>
16
16
  </header>
17
-
17
+
18
18
  <div class="table-wrapper">
19
19
  <table class="summary" border="none">
20
20
  <thead>
@@ -29,26 +29,26 @@
29
29
  </thead>
30
30
  <tbody>
31
31
  <tr>
32
- <td class="name"><%= file['path'] %></td>
33
- <td><%= file['lines'] %></td>
34
- <td><%= file['lines_code']%></td>
35
- <td><%= file['lines_ran']%></td>
36
- <td><%= coverage['total']%></td>
37
- <td><%= coverage['code']%></td>
32
+ <td class="name"><%= file.path %></td>
33
+ <td><%= lines.total %></td>
34
+ <td><%= lines.code %></td>
35
+ <td><%= lines.ran %></td>
36
+ <td><%= coverage.total %></td>
37
+ <td><%= coverage.code %></td>
38
38
  </tr>
39
39
  </tbody>
40
40
  </table>
41
41
  </div>
42
-
42
+
43
43
  <div class="table-wrapper">
44
44
  <table class="source" border="none">
45
- <% file['source'].zip(coverage['lines']).each_with_index do |(line, count), i| %>
45
+ <% file.source.zip(coverage.lines).each_with_index do |(line, count), i| %>
46
46
  <% if count.nil? %>
47
47
  <tr class="excluded">
48
48
  <td class="no"><%= i %></td>
49
49
  <td><pre><code><%= line %></code></pre></td>
50
50
  </tr>
51
-
51
+
52
52
  <% else %>
53
53
  <tr class="<%= count.zero? ? "unran" : "ran" %>">
54
54
  <td class="no"><%= i %></td>
@@ -58,14 +58,13 @@
58
58
  <% end %>
59
59
  </table>
60
60
  </div>
61
-
62
-
61
+
62
+
63
63
  <footer>
64
64
  <span>
65
- Generated at <%= time %> with
65
+ Generated at <%= time %> with
66
66
  <a href="http://github.com/hawx/duvet"><%= name %> <%= version %></a>
67
67
  </span>
68
68
  </footer>
69
69
  </body>
70
70
  </html>
71
-