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.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +5 -15
  4. data/.travis.yml +1 -0
  5. data/LICENSE +1 -1
  6. data/LICENSE.txt +1 -1
  7. data/README.md +19 -2
  8. data/Rakefile +1 -1
  9. data/changes.md +3 -0
  10. data/coverband.gemspec +7 -4
  11. data/lib/coverband.rb +2 -3
  12. data/lib/coverband/configuration.rb +5 -1
  13. data/lib/coverband/integrations/background.rb +19 -10
  14. data/lib/coverband/reporters/html_report.rb +5 -1
  15. data/lib/coverband/reporters/web.rb +6 -59
  16. data/lib/coverband/utils/html_formatter.rb +18 -2
  17. data/lib/coverband/utils/result.rb +1 -0
  18. data/lib/coverband/utils/s3_report.rb +1 -1
  19. data/lib/coverband/utils/source_file.rb +1 -1
  20. data/lib/coverband/version.rb +1 -1
  21. data/public/application.css +37 -3
  22. data/public/application.js +50 -44
  23. data/test/fixtures/app/controllers/sample_controller.rb +10 -0
  24. data/test/fixtures/app/models/user.rb +10 -0
  25. data/test/fixtures/never.rb +2 -0
  26. data/test/fixtures/sample.rb +16 -0
  27. data/test/fixtures/skipped.rb +4 -0
  28. data/test/fixtures/skipped_and_executed.rb +8 -0
  29. data/test/fixtures/utf-8.rb +3 -0
  30. data/test/rails4_dummy/config/coverband.rb +1 -1
  31. data/test/rails4_dummy/config/routes.rb +1 -0
  32. data/test/rails5_dummy/config/coverband.rb +3 -2
  33. data/test/rails5_dummy/config/routes.rb +1 -0
  34. data/test/rails_test_helper.rb +6 -6
  35. data/test/test_helper.rb +50 -2
  36. data/test/unit/adapters_base_test.rb +2 -1
  37. data/test/unit/adapters_file_store_test.rb +2 -1
  38. data/test/unit/adapters_redis_store_test.rb +2 -1
  39. data/test/unit/background_test.rb +12 -7
  40. data/test/unit/collectors_coverage_test.rb +3 -2
  41. data/test/unit/configuration_test.rb +2 -1
  42. data/test/unit/coverband_test.rb +1 -1
  43. data/test/unit/full_stack_test.rb +1 -1
  44. data/test/unit/middleware_test.rb +2 -1
  45. data/test/unit/rack_server_checkout_test.rb +7 -8
  46. data/test/unit/rails_full_stack_test.rb +26 -10
  47. data/test/unit/reports_base_test.rb +1 -1
  48. data/test/unit/reports_console_test.rb +2 -1
  49. data/test/unit/reports_html_test.rb +2 -1
  50. data/test/unit/reports_web_test.rb +3 -2
  51. data/test/unit/utils/file_list_test.rb +54 -0
  52. data/test/unit/utils/lines_classifier_test.rb +109 -0
  53. data/test/unit/utils/result_test.rb +104 -0
  54. data/test/unit/{utils_s3_report_test.rb → utils/s3_report_test.rb} +4 -4
  55. data/test/unit/utils/source_file_line_test.rb +165 -0
  56. data/test/unit/utils/source_file_test.rb +149 -0
  57. data/views/layout.erb +10 -1
  58. metadata +65 -13
  59. data/Gemfile.rails4.lock +0 -164
@@ -43,6 +43,7 @@ module Coverband
43
43
  end
44
44
 
45
45
  # Returns a Hash of groups for this result. Define groups using SimpleCov.add_group 'Models', 'app/models'
46
+ # Coverband doesn't currently support groups
46
47
  def groups
47
48
  @groups ||= [] # SimpleCov.grouped(files)
48
49
  end
@@ -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 false # SimpleCov::LinesClassifier.no_cov_line?(line.src)
189
+ if Coverband::Utils::LinesClassifier.no_cov_line?(line.src)
190
190
  skipping = !skipping
191
191
  line.skipped!
192
192
  elsif skipping
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coverband
4
- VERSION = '4.0.1.alpha'
4
+ VERSION = '4.0.1.beta'
5
5
  end
@@ -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
-
@@ -1114,14 +1114,14 @@ var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").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" ]],
@@ -0,0 +1,10 @@
1
+ # Foo class
2
+ class Foo
3
+ def initialize
4
+ @foo = 'baz'
5
+ end
6
+
7
+ def bar
8
+ @foo
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # Foo class
2
+ class Foo
3
+ def initialize
4
+ @foo = 'baz'
5
+ end
6
+
7
+ def bar
8
+ @foo
9
+ end
10
+ end
@@ -0,0 +1,2 @@
1
+ # This class is purely some
2
+ # comments
@@ -0,0 +1,16 @@
1
+ # Foo class
2
+ class Foo
3
+ def initialize
4
+ @foo = 'baz'
5
+ end
6
+
7
+ def bar
8
+ @foo
9
+ end
10
+
11
+ #:nocov:
12
+ def skipped
13
+ @foo * 2
14
+ end
15
+ #:nocov:
16
+ end
@@ -0,0 +1,4 @@
1
+ # Not relevant
2
+ # :nocov:
3
+ # Hash.new
4
+ # :nocov:
@@ -0,0 +1,8 @@
1
+ # So much skippping
2
+ # :nocov:
3
+ class Foo
4
+ def bar
5
+ 0
6
+ end
7
+ end
8
+ #:nocov:
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ puts "135°C"
@@ -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
@@ -1,3 +1,4 @@
1
1
  Rails.application.routes.draw do
2
2
  get 'dummy/show'
3
+ mount Coverband::Reporters::Web.new, at: '/coverage'
3
4
  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.reporting_frequency = 100.0
7
- config.logger = Rails.logger
6
+ config.logger = Rails.logger
7
+ config.verbose = true
8
+ config.background_reporting_sleep_seconds = 0.1
8
9
  end
@@ -1,3 +1,4 @@
1
1
  Rails.application.routes.draw do
2
2
  get 'dummy/show'
3
+ mount Coverband::Reporters::Web.new, at: '/coverage'
3
4
  end
@@ -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
- if Rails::VERSION::MAJOR >= 5
7
- require_relative "../test/rails5_dummy/config/environment"
8
- else
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 'test/unit'
6
- require 'mocha/setup'
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