coverband 4.0.1.alpha → 4.0.1.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -1
- data/.rubocop.yml +5 -15
- data/.travis.yml +1 -0
- data/LICENSE +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +19 -2
- data/Rakefile +1 -1
- data/changes.md +3 -0
- data/coverband.gemspec +7 -4
- data/lib/coverband.rb +2 -3
- data/lib/coverband/configuration.rb +5 -1
- data/lib/coverband/integrations/background.rb +19 -10
- data/lib/coverband/reporters/html_report.rb +5 -1
- data/lib/coverband/reporters/web.rb +6 -59
- data/lib/coverband/utils/html_formatter.rb +18 -2
- data/lib/coverband/utils/result.rb +1 -0
- data/lib/coverband/utils/s3_report.rb +1 -1
- data/lib/coverband/utils/source_file.rb +1 -1
- data/lib/coverband/version.rb +1 -1
- data/public/application.css +37 -3
- data/public/application.js +50 -44
- data/test/fixtures/app/controllers/sample_controller.rb +10 -0
- data/test/fixtures/app/models/user.rb +10 -0
- data/test/fixtures/never.rb +2 -0
- data/test/fixtures/sample.rb +16 -0
- data/test/fixtures/skipped.rb +4 -0
- data/test/fixtures/skipped_and_executed.rb +8 -0
- data/test/fixtures/utf-8.rb +3 -0
- data/test/rails4_dummy/config/coverband.rb +1 -1
- data/test/rails4_dummy/config/routes.rb +1 -0
- data/test/rails5_dummy/config/coverband.rb +3 -2
- data/test/rails5_dummy/config/routes.rb +1 -0
- data/test/rails_test_helper.rb +6 -6
- data/test/test_helper.rb +50 -2
- data/test/unit/adapters_base_test.rb +2 -1
- data/test/unit/adapters_file_store_test.rb +2 -1
- data/test/unit/adapters_redis_store_test.rb +2 -1
- data/test/unit/background_test.rb +12 -7
- data/test/unit/collectors_coverage_test.rb +3 -2
- data/test/unit/configuration_test.rb +2 -1
- data/test/unit/coverband_test.rb +1 -1
- data/test/unit/full_stack_test.rb +1 -1
- data/test/unit/middleware_test.rb +2 -1
- data/test/unit/rack_server_checkout_test.rb +7 -8
- data/test/unit/rails_full_stack_test.rb +26 -10
- data/test/unit/reports_base_test.rb +1 -1
- data/test/unit/reports_console_test.rb +2 -1
- data/test/unit/reports_html_test.rb +2 -1
- data/test/unit/reports_web_test.rb +3 -2
- data/test/unit/utils/file_list_test.rb +54 -0
- data/test/unit/utils/lines_classifier_test.rb +109 -0
- data/test/unit/utils/result_test.rb +104 -0
- data/test/unit/{utils_s3_report_test.rb → utils/s3_report_test.rb} +4 -4
- data/test/unit/utils/source_file_line_test.rb +165 -0
- data/test/unit/utils/source_file_test.rb +149 -0
- data/views/layout.erb +10 -1
- metadata +65 -13
- data/Gemfile.rails4.lock +0 -164
@@ -24,7 +24,7 @@ module Coverband
|
|
24
24
|
@access_key_id = options[:access_key_id]
|
25
25
|
@secret_access_key = options[:secret_access_key]
|
26
26
|
begin
|
27
|
-
require 'aws-sdk'
|
27
|
+
require 'aws-sdk-s3'
|
28
28
|
rescue StandardError
|
29
29
|
err_msg = 'coverband requires aws-sdk in order use S3Report.'
|
30
30
|
Coverband.configuration.logger.error err_msg
|
@@ -186,7 +186,7 @@ module Coverband
|
|
186
186
|
skipping = false
|
187
187
|
|
188
188
|
lines.each do |line|
|
189
|
-
if
|
189
|
+
if Coverband::Utils::LinesClassifier.no_cov_line?(line.src)
|
190
190
|
skipping = !skipping
|
191
191
|
line.skipped!
|
192
192
|
elsif skipping
|
data/lib/coverband/version.rb
CHANGED
data/public/application.css
CHANGED
@@ -748,6 +748,43 @@ td {
|
|
748
748
|
text-align: center;
|
749
749
|
border-radius: 6px; }
|
750
750
|
|
751
|
+
#header {
|
752
|
+
color: #FFF;
|
753
|
+
font-size: 12px;
|
754
|
+
font-weight: bold;
|
755
|
+
margin-bottom: 12px;
|
756
|
+
text-align: left; }
|
757
|
+
#header a {
|
758
|
+
color: #FFF;
|
759
|
+
text-decoration: underline; }
|
760
|
+
#header a:hover {
|
761
|
+
color: white;
|
762
|
+
text-decoration: none; }
|
763
|
+
#header a:hover {
|
764
|
+
color: white;
|
765
|
+
text-decoration: none; }
|
766
|
+
|
767
|
+
.coveraband-button-improve {
|
768
|
+
background-color: #4CAF50; /* Green */
|
769
|
+
border: none;
|
770
|
+
color: white;
|
771
|
+
padding: 15px 32px;
|
772
|
+
text-align: center;
|
773
|
+
text-decoration: none;
|
774
|
+
display: inline-block;
|
775
|
+
font-size: 16px;
|
776
|
+
}
|
777
|
+
|
778
|
+
.coverband-admin-form {
|
779
|
+
display: inline-block;
|
780
|
+
}
|
781
|
+
|
782
|
+
.notice {
|
783
|
+
color: #856404;
|
784
|
+
background-color: #fff3cd;
|
785
|
+
border-color: #ffeeba;
|
786
|
+
}
|
787
|
+
|
751
788
|
#footer {
|
752
789
|
color: #dddddd;
|
753
790
|
font-size: 12px;
|
@@ -794,6 +831,3 @@ td {
|
|
794
831
|
background-color: #fbf0c0; }
|
795
832
|
.source_table .skipped:nth-child(even) {
|
796
833
|
background-color: #fbffcf; }
|
797
|
-
|
798
|
-
|
799
|
-
|
data/public/application.js
CHANGED
@@ -1114,14 +1114,14 @@ var hljs=new function(){function l(o){return o.replace(/&/gm,"&").replace(/<
|
|
1114
1114
|
* Version: 1.7.0
|
1115
1115
|
* Author: Allan Jardine (www.sprymedia.co.uk)
|
1116
1116
|
* Info: www.datatables.net
|
1117
|
-
*
|
1117
|
+
*
|
1118
1118
|
* Copyright 2008-2010 Allan Jardine, all rights reserved.
|
1119
1119
|
*
|
1120
1120
|
* This source file is free software, under either the GPL v2 license or a
|
1121
1121
|
* BSD style license, as supplied with this software.
|
1122
|
-
*
|
1123
|
-
* This source file is distributed in the hope that it will be useful, but
|
1124
|
-
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
1122
|
+
*
|
1123
|
+
* This source file is distributed in the hope that it will be useful, but
|
1124
|
+
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
1125
1125
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
1126
1126
|
*/
|
1127
1127
|
|
@@ -1411,40 +1411,40 @@ jQuery.fn.dataTableExt.oSort['percent-desc'] = function(a,b) {
|
|
1411
1411
|
jQuery.url = function()
|
1412
1412
|
{
|
1413
1413
|
var segments = {};
|
1414
|
-
|
1414
|
+
|
1415
1415
|
var parsed = {};
|
1416
|
-
|
1416
|
+
|
1417
1417
|
/**
|
1418
1418
|
* Options object. Only the URI and strictMode values can be changed via the setters below.
|
1419
1419
|
*/
|
1420
1420
|
var options = {
|
1421
|
-
|
1421
|
+
|
1422
1422
|
url : window.location, // default URI is the page in which the script is running
|
1423
|
-
|
1423
|
+
|
1424
1424
|
strictMode: false, // 'loose' parsing by default
|
1425
|
-
|
1426
|
-
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], // keys available to query
|
1427
|
-
|
1425
|
+
|
1426
|
+
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], // keys available to query
|
1427
|
+
|
1428
1428
|
q: {
|
1429
1429
|
name: "queryKey",
|
1430
1430
|
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
|
1431
1431
|
},
|
1432
|
-
|
1432
|
+
|
1433
1433
|
parser: {
|
1434
1434
|
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs
|
1435
1435
|
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs
|
1436
1436
|
}
|
1437
|
-
|
1437
|
+
|
1438
1438
|
};
|
1439
|
-
|
1439
|
+
|
1440
1440
|
/**
|
1441
1441
|
* Deals with the parsing of the URI according to the regex above.
|
1442
1442
|
* Written by Steven Levithan - see credits at top.
|
1443
|
-
*/
|
1443
|
+
*/
|
1444
1444
|
var parseUri = function()
|
1445
1445
|
{
|
1446
1446
|
str = decodeURI( options.url );
|
1447
|
-
|
1447
|
+
|
1448
1448
|
var m = options.parser[ options.strictMode ? "strict" : "loose" ].exec( str );
|
1449
1449
|
var uri = {};
|
1450
1450
|
var i = 14;
|
@@ -1465,55 +1465,55 @@ jQuery.url = function()
|
|
1465
1465
|
|
1466
1466
|
/**
|
1467
1467
|
* Returns the value of the passed in key from the parsed URI.
|
1468
|
-
*
|
1468
|
+
*
|
1469
1469
|
* @param string key The key whose value is required
|
1470
|
-
*/
|
1470
|
+
*/
|
1471
1471
|
var key = function( key )
|
1472
1472
|
{
|
1473
1473
|
if ( ! parsed.length )
|
1474
1474
|
{
|
1475
|
-
setUp(); // if the URI has not been parsed yet then do this first...
|
1476
|
-
}
|
1475
|
+
setUp(); // if the URI has not been parsed yet then do this first...
|
1476
|
+
}
|
1477
1477
|
if ( key == "base" )
|
1478
1478
|
{
|
1479
1479
|
if ( parsed.port !== null && parsed.port !== "" )
|
1480
1480
|
{
|
1481
|
-
return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/";
|
1481
|
+
return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/";
|
1482
1482
|
}
|
1483
1483
|
else
|
1484
1484
|
{
|
1485
1485
|
return parsed.protocol+"://"+parsed.host+"/";
|
1486
1486
|
}
|
1487
1487
|
}
|
1488
|
-
|
1488
|
+
|
1489
1489
|
return ( parsed[key] === "" ) ? null : parsed[key];
|
1490
1490
|
};
|
1491
|
-
|
1491
|
+
|
1492
1492
|
/**
|
1493
1493
|
* Returns the value of the required query string parameter.
|
1494
|
-
*
|
1494
|
+
*
|
1495
1495
|
* @param string item The parameter whose value is required
|
1496
|
-
*/
|
1496
|
+
*/
|
1497
1497
|
var param = function( item )
|
1498
1498
|
{
|
1499
1499
|
if ( ! parsed.length )
|
1500
1500
|
{
|
1501
|
-
setUp(); // if the URI has not been parsed yet then do this first...
|
1501
|
+
setUp(); // if the URI has not been parsed yet then do this first...
|
1502
1502
|
}
|
1503
1503
|
return ( parsed.queryKey[item] === null ) ? null : parsed.queryKey[item];
|
1504
1504
|
};
|
1505
1505
|
|
1506
1506
|
/**
|
1507
1507
|
* 'Constructor' (not really!) function.
|
1508
|
-
* Called whenever the URI changes to kick off re-parsing of the URI and splitting it up into segments.
|
1509
|
-
*/
|
1508
|
+
* Called whenever the URI changes to kick off re-parsing of the URI and splitting it up into segments.
|
1509
|
+
*/
|
1510
1510
|
var setUp = function()
|
1511
1511
|
{
|
1512
1512
|
parsed = parseUri();
|
1513
|
-
|
1514
|
-
getSegments();
|
1513
|
+
|
1514
|
+
getSegments();
|
1515
1515
|
};
|
1516
|
-
|
1516
|
+
|
1517
1517
|
/**
|
1518
1518
|
* Splits up the body of the URI into segments (i.e. sections delimited by '/')
|
1519
1519
|
*/
|
@@ -1523,9 +1523,9 @@ jQuery.url = function()
|
|
1523
1523
|
segments = []; // clear out segments array
|
1524
1524
|
segments = parsed.path.length == 1 ? {} : ( p.charAt( p.length - 1 ) == "/" ? p.substring( 1, p.length - 1 ) : path = p.substring( 1 ) ).split("/");
|
1525
1525
|
};
|
1526
|
-
|
1526
|
+
|
1527
1527
|
return {
|
1528
|
-
|
1528
|
+
|
1529
1529
|
/**
|
1530
1530
|
* Sets the parsing mode - either strict or loose. Set to loose by default.
|
1531
1531
|
*
|
@@ -1536,20 +1536,20 @@ jQuery.url = function()
|
|
1536
1536
|
strictMode = mode == "strict" ? true : false;
|
1537
1537
|
return this;
|
1538
1538
|
},
|
1539
|
-
|
1539
|
+
|
1540
1540
|
/**
|
1541
1541
|
* Sets URI to parse if you don't want to to parse the current page's URI.
|
1542
1542
|
* Calling the function with no value for newUri resets it to the current page's URI.
|
1543
1543
|
*
|
1544
1544
|
* @param string newUri The URI to parse.
|
1545
|
-
*/
|
1545
|
+
*/
|
1546
1546
|
setUrl : function( newUri )
|
1547
1547
|
{
|
1548
1548
|
options.url = newUri === undefined ? window.location : newUri;
|
1549
1549
|
setUp();
|
1550
1550
|
return this;
|
1551
|
-
},
|
1552
|
-
|
1551
|
+
},
|
1552
|
+
|
1553
1553
|
/**
|
1554
1554
|
* Returns the value of the specified URI segment. Segments are numbered from 1 to the number of segments.
|
1555
1555
|
* For example the URI http://test.com/about/company/ segment(1) would return 'about'.
|
@@ -1557,32 +1557,38 @@ jQuery.url = function()
|
|
1557
1557
|
* If no integer is passed into the function it returns the number of segments in the URI.
|
1558
1558
|
*
|
1559
1559
|
* @param int pos The position of the segment to return. Can be empty.
|
1560
|
-
*/
|
1560
|
+
*/
|
1561
1561
|
segment : function( pos )
|
1562
1562
|
{
|
1563
1563
|
if ( ! parsed.length )
|
1564
1564
|
{
|
1565
|
-
setUp(); // if the URI has not been parsed yet then do this first...
|
1566
|
-
}
|
1565
|
+
setUp(); // if the URI has not been parsed yet then do this first...
|
1566
|
+
}
|
1567
1567
|
if ( pos === undefined )
|
1568
1568
|
{
|
1569
1569
|
return segments.length;
|
1570
1570
|
}
|
1571
1571
|
return ( segments[pos] === "" || segments[pos] === undefined ) ? null : segments[pos];
|
1572
1572
|
},
|
1573
|
-
|
1573
|
+
|
1574
1574
|
attr : key, // provides public access to private 'key' function - see above
|
1575
|
-
|
1575
|
+
|
1576
1576
|
param : param // provides public access to private 'param' function - see above
|
1577
|
-
|
1577
|
+
|
1578
1578
|
};
|
1579
|
-
|
1579
|
+
|
1580
1580
|
}();
|
1581
1581
|
|
1582
1582
|
|
1583
1583
|
|
1584
1584
|
|
1585
1585
|
$(document).ready(function() {
|
1586
|
+
$(".del").click(function(){
|
1587
|
+
if (!confirm("Do you want to delete")){
|
1588
|
+
return false;
|
1589
|
+
}
|
1590
|
+
});
|
1591
|
+
|
1586
1592
|
// Configuration for fancy sortable tables for source file groups
|
1587
1593
|
$('.file_list').dataTable({
|
1588
1594
|
"aaSorting": [[ 1, "asc" ]],
|
@@ -3,6 +3,6 @@ Coverband.configure do |config|
|
|
3
3
|
config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: ENV['REDIS_URL'])) if defined? Redis
|
4
4
|
config.ignore = %w[vendor .erb$ .slim$]
|
5
5
|
config.root_paths = []
|
6
|
-
config.reporting_frequency = 100.0
|
7
6
|
config.logger = Rails.logger
|
7
|
+
config.background_reporting_sleep_seconds = 0.1
|
8
8
|
end
|
@@ -3,6 +3,7 @@ Coverband.configure do |config|
|
|
3
3
|
config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: ENV['REDIS_URL'])) if defined? Redis
|
4
4
|
config.ignore = %w[vendor .erb$ .slim$]
|
5
5
|
config.root_paths = []
|
6
|
-
config.
|
7
|
-
config.
|
6
|
+
config.logger = Rails.logger
|
7
|
+
config.verbose = true
|
8
|
+
config.background_reporting_sleep_seconds = 0.1
|
8
9
|
end
|
data/test/rails_test_helper.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
ENV["RAILS_ENV"] = "test"
|
3
3
|
require 'rails'
|
4
4
|
require File.expand_path('./test_helper', File.dirname(__FILE__))
|
5
|
+
require_relative "../test/rails#{Rails::VERSION::MAJOR}_dummy/config/environment"
|
6
|
+
require 'capybara/rails'
|
7
|
+
require 'capybara/minitest'
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require_relative "../test/rails4_dummy/config/environment"
|
10
|
-
end
|
11
|
-
|
9
|
+
#Our coverage report is wrapped in display:none as of now
|
10
|
+
Capybara.ignore_hidden_elements = false
|
11
|
+
require 'mocha/minitest'
|
data/test/test_helper.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# This lets us ignore warnings from our test dependencies when loaded
|
4
|
+
# We do this because of aws-sdk-s3
|
5
|
+
# aws-sdk-s3 is written in such a way to cause dozens of warnings
|
6
|
+
original_verbosity = $VERBOSE
|
7
|
+
$VERBOSE = nil
|
3
8
|
require 'rubygems'
|
9
|
+
require 'aws-sdk-s3'
|
10
|
+
require 'coveralls'
|
4
11
|
require 'simplecov'
|
5
|
-
require '
|
6
|
-
require 'mocha/
|
12
|
+
require 'minitest/autorun'
|
13
|
+
require 'mocha/minitest'
|
7
14
|
require 'ostruct'
|
8
15
|
require 'json'
|
9
16
|
require 'redis'
|
10
17
|
require 'pry-byebug'
|
18
|
+
$VERBOSE = original_verbosity
|
19
|
+
|
20
|
+
Coveralls.wear!
|
11
21
|
|
12
22
|
SimpleCov.start do
|
13
23
|
add_filter 'specs/ruby/1.9.1/gems/'
|
@@ -15,6 +25,26 @@ SimpleCov.start do
|
|
15
25
|
add_filter '/config/'
|
16
26
|
end
|
17
27
|
|
28
|
+
module Coverband
|
29
|
+
module Test
|
30
|
+
def self.reset
|
31
|
+
Coverband.configuration.store.clear!
|
32
|
+
Coverband.configuration.reset
|
33
|
+
Coverband::Collectors::Coverage.instance.reset_instance
|
34
|
+
Coverband::Background.stop
|
35
|
+
end
|
36
|
+
|
37
|
+
def setup
|
38
|
+
super
|
39
|
+
Coverband::Test.reset
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Minitest::Test.class_eval do
|
45
|
+
prepend Coverband::Test
|
46
|
+
end
|
47
|
+
|
18
48
|
TEST_COVERAGE_FILE = '/tmp/fake_file.json'
|
19
49
|
|
20
50
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
@@ -66,6 +96,24 @@ def fake_coverage_report
|
|
66
96
|
{ file_name => [1, nil, 1, 1, nil, nil, nil] }
|
67
97
|
end
|
68
98
|
|
99
|
+
def source_fixture(filename)
|
100
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', filename))
|
101
|
+
end
|
102
|
+
|
103
|
+
# Taken from http://stackoverflow.com/questions/4459330/how-do-i-temporarily-redirect-stderr-in-ruby
|
104
|
+
def capture_stderr
|
105
|
+
# The output stream must be an IO-like object. In this case we capture it in
|
106
|
+
# an in-memory IO object so we can return the string value. You can assign any
|
107
|
+
# IO object here.
|
108
|
+
previous_stderr = $stderr
|
109
|
+
$stderr = StringIO.new
|
110
|
+
yield
|
111
|
+
$stderr.string
|
112
|
+
ensure
|
113
|
+
# Restore the previous value of stderr (typically equal to STDERR).
|
114
|
+
$stderr = previous_stderr
|
115
|
+
end
|
116
|
+
|
69
117
|
require 'coverband'
|
70
118
|
|
71
119
|
Coverband::Configuration.class_eval do
|