deep-cover 0.1.16 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +3 -8
- data/.travis.yml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile +3 -1
- data/README.md +9 -4
- data/Rakefile +6 -3
- data/deep_cover.gemspec +2 -2
- data/lib/deep_cover.rb +10 -0
- data/lib/deep_cover/analyser.rb +1 -2
- data/lib/deep_cover/analyser/base.rb +32 -0
- data/lib/deep_cover/analyser/branch.rb +19 -4
- data/lib/deep_cover/analyser/node.rb +52 -0
- data/lib/deep_cover/analyser/per_char.rb +18 -1
- data/lib/deep_cover/analyser/stats.rb +54 -0
- data/lib/deep_cover/backports.rb +1 -0
- data/lib/deep_cover/base.rb +17 -1
- data/lib/deep_cover/builtin_takeover.rb +5 -0
- data/lib/deep_cover/cli/deep_cover.rb +2 -1
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +12 -10
- data/lib/deep_cover/config.rb +22 -8
- data/lib/deep_cover/core_ext/coverage_replacement.rb +22 -18
- data/lib/deep_cover/coverage.rb +3 -203
- data/lib/deep_cover/coverage/analysis.rb +36 -0
- data/lib/deep_cover/coverage/base.rb +91 -0
- data/lib/deep_cover/coverage/istanbul.rb +34 -0
- data/lib/deep_cover/coverage/persistence.rb +93 -0
- data/lib/deep_cover/covered_code.rb +12 -22
- data/lib/deep_cover/custom_requirer.rb +6 -2
- data/lib/deep_cover/node/base.rb +1 -1
- data/lib/deep_cover/node/case.rb +13 -2
- data/lib/deep_cover/node/exceptions.rb +2 -2
- data/lib/deep_cover/node/if.rb +21 -2
- data/lib/deep_cover/node/mixin/flow_accounting.rb +1 -0
- data/lib/deep_cover/node/send.rb +9 -2
- data/lib/deep_cover/node/short_circuit.rb +10 -0
- data/lib/deep_cover/parser_ext/range.rb +4 -4
- data/lib/deep_cover/reporter/html.rb +15 -0
- data/lib/deep_cover/reporter/html/base.rb +14 -0
- data/lib/deep_cover/reporter/html/index.rb +78 -0
- data/lib/deep_cover/reporter/html/site.rb +78 -0
- data/lib/deep_cover/reporter/html/source.rb +136 -0
- data/lib/deep_cover/reporter/html/template/assets/32px.png +0 -0
- data/lib/deep_cover/reporter/html/template/assets/40px.png +0 -0
- data/lib/deep_cover/reporter/html/template/assets/deep_cover.css.sass +338 -0
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.js +4 -0
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.map +1 -0
- data/lib/deep_cover/reporter/html/template/assets/jstree.css +1108 -0
- data/lib/deep_cover/reporter/html/template/assets/jstree.js +8424 -0
- data/lib/deep_cover/reporter/html/template/assets/jstreetable.js +1069 -0
- data/lib/deep_cover/reporter/html/template/assets/throbber.gif +0 -0
- data/lib/deep_cover/reporter/html/template/index.html.erb +75 -0
- data/lib/deep_cover/reporter/html/template/source.html.erb +35 -0
- data/lib/deep_cover/reporter/html/tree.rb +55 -0
- data/lib/deep_cover/tools/content_tag.rb +11 -0
- data/lib/deep_cover/tools/covered.rb +9 -0
- data/lib/deep_cover/tools/merge.rb +16 -0
- data/lib/deep_cover/tools/render_template.rb +13 -0
- data/lib/deep_cover/tools/transform_keys.rb +9 -0
- data/lib/deep_cover/version.rb +1 -1
- metadata +33 -7
- data/lib/deep_cover/analyser/ignore_uncovered.rb +0 -21
- data/lib/deep_cover/analyser/optionally_covered.rb +0 -19
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
module Reporter::HTML::Base
|
5
|
+
include Tools::ContentTag
|
6
|
+
def setup
|
7
|
+
DeepCover::Config::DEFAULTS.keys.map do |setting|
|
8
|
+
value = options[setting]
|
9
|
+
value = value.join(', ') if value.respond_to? :join
|
10
|
+
content_tag :span, value, class: setting
|
11
|
+
end.join
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
module Reporter
|
5
|
+
require_relative 'tree'
|
6
|
+
require_relative 'base'
|
7
|
+
|
8
|
+
class HTML::Index < Struct.new(:analysis, :options)
|
9
|
+
def initialize(analysis, **options)
|
10
|
+
raise ArgumentError unless analysis.is_a? Coverage::Analysis
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
include HTML::Tree
|
15
|
+
include HTML::Base
|
16
|
+
|
17
|
+
def stats_to_data
|
18
|
+
@map = Tools.transform_keys(analysis.stat_map, &:name)
|
19
|
+
tree = paths_to_tree(@map.keys)
|
20
|
+
transform_data(populate(tree))
|
21
|
+
end
|
22
|
+
|
23
|
+
def columns
|
24
|
+
_covered_code, analyser_map = analysis.analyser_map.first
|
25
|
+
columns = analyser_map.flat_map do |type, analyser|
|
26
|
+
[{
|
27
|
+
value: type,
|
28
|
+
header: analyser.class.human_name,
|
29
|
+
}, {
|
30
|
+
value: :"#{type}_percent",
|
31
|
+
header: '%',
|
32
|
+
},
|
33
|
+
]
|
34
|
+
end
|
35
|
+
columns.unshift(width: 400, header: 'Path')
|
36
|
+
columns
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# {a: {}} => [{text: a, data: stat_map[a]}]
|
42
|
+
# {b: {...}} => [{text: b, data: sum(stats), children: [...]}]
|
43
|
+
def populate(tree, dir = '')
|
44
|
+
tree.map do |path, children_hash|
|
45
|
+
full_path = [dir, path].join
|
46
|
+
if children_hash.empty?
|
47
|
+
{
|
48
|
+
text: %{<a href="#{full_path}.html">#{path}</a>},
|
49
|
+
data: @map[full_path],
|
50
|
+
}
|
51
|
+
else
|
52
|
+
children = populate(children_hash, "#{full_path}/")
|
53
|
+
data = Tools.merge(*children.map { |c| c[:data] }, :+)
|
54
|
+
{
|
55
|
+
text: path,
|
56
|
+
data: data,
|
57
|
+
children: children,
|
58
|
+
state: {opened: true},
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Modifies in place the tree:
|
65
|
+
# {per_char: Stat, ...} => {per_char: {ignored: ...}, per_char_percent: 55.55, ...}
|
66
|
+
def transform_data(tree)
|
67
|
+
return unless tree
|
68
|
+
tree.each do |node|
|
69
|
+
node[:data] = Tools.merge(
|
70
|
+
node[:data].transform_values(&:to_h),
|
71
|
+
*node[:data].map { |type, stat| {:"#{type}_percent" => stat.percent_covered} }
|
72
|
+
)
|
73
|
+
transform_data(node[:children])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
require_relative 'index'
|
5
|
+
require_relative 'source'
|
6
|
+
|
7
|
+
module Reporter::HTML
|
8
|
+
class Site < Struct.new(:covered_codes, :options)
|
9
|
+
def initialize(covered_codes, **options)
|
10
|
+
raise ArgumentError unless covered_codes.all? { |c| c.is_a? CoveredCode }
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
include Memoize
|
15
|
+
memoize :analysis
|
16
|
+
|
17
|
+
def analysis
|
18
|
+
Coverage::Analysis.new(covered_codes, **options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def path
|
22
|
+
Pathname(options[:output])
|
23
|
+
end
|
24
|
+
|
25
|
+
def save
|
26
|
+
clear
|
27
|
+
save_assets
|
28
|
+
save_index
|
29
|
+
save_pages
|
30
|
+
end
|
31
|
+
|
32
|
+
def clear
|
33
|
+
path.mkpath
|
34
|
+
path.rmtree
|
35
|
+
path.mkpath
|
36
|
+
end
|
37
|
+
|
38
|
+
def compile_stylesheet(source, dest)
|
39
|
+
Bundler.with_clean_env do
|
40
|
+
`sass #{source} #{dest}`
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def render_index
|
45
|
+
Tools.render_template(:index, Index.new(analysis, **options))
|
46
|
+
end
|
47
|
+
|
48
|
+
def save_index
|
49
|
+
path.join('index.html').write(render_index)
|
50
|
+
end
|
51
|
+
|
52
|
+
def save_assets
|
53
|
+
require 'fileutils'
|
54
|
+
src = "#{__dir__}/template/assets"
|
55
|
+
dest = path.join('assets')
|
56
|
+
FileUtils.cp_r(src, dest)
|
57
|
+
compile_stylesheet "#{src}/deep_cover.css.sass", dest.join('deep_cover.css')
|
58
|
+
dest.join('deep_cover.css.sass').delete
|
59
|
+
end
|
60
|
+
|
61
|
+
def render_source(covered_code)
|
62
|
+
Tools.render_template(:source, Source.new(analysis.analyser_map.fetch(covered_code)))
|
63
|
+
end
|
64
|
+
|
65
|
+
def save_pages
|
66
|
+
covered_codes.each do |covered_code|
|
67
|
+
dest = path.join("#{covered_code.name}.html")
|
68
|
+
dest.dirname.mkpath
|
69
|
+
dest.write(render_source(covered_code))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.save(covered_codes, output: raise, **options)
|
74
|
+
Site.new(covered_codes, output: output, **options).save
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
module Reporter
|
5
|
+
require_relative 'base'
|
6
|
+
|
7
|
+
class HTML::Source < Struct.new(:analyser_map)
|
8
|
+
include Tools::Covered
|
9
|
+
|
10
|
+
def initialize(analyser_map)
|
11
|
+
raise ArgumentError unless analyser_map.values.all? { |a| a.is_a?(Analyser) }
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
include HTML::Base
|
16
|
+
|
17
|
+
def format_source
|
18
|
+
lines = convert_source.split("\n")
|
19
|
+
lines.map { |line| content_tag(:td, line) }
|
20
|
+
rows = lines.map.with_index do |line, i|
|
21
|
+
nb = content_tag(:td, i + 1, id: "L#{i + 1}", class: :nb)
|
22
|
+
content_tag(:tr, nb + content_tag(:td, line))
|
23
|
+
end
|
24
|
+
content_tag(:table, rows.join, class: :source)
|
25
|
+
end
|
26
|
+
|
27
|
+
def convert_source
|
28
|
+
@rewriter = ::Parser::Source::TreeRewriter.new(covered_code.buffer)
|
29
|
+
insert_node_tags
|
30
|
+
insert_branch_tags
|
31
|
+
html_escape
|
32
|
+
@rewriter.process
|
33
|
+
end
|
34
|
+
|
35
|
+
def root_path
|
36
|
+
Pathname('.').relative_path_from(Pathname(covered_code.name).dirname)
|
37
|
+
end
|
38
|
+
|
39
|
+
def stats
|
40
|
+
cells = analyser_map.map do |type, analyser|
|
41
|
+
data = analyser.stats
|
42
|
+
f = ->(kind) { content_tag(:span, data.public_send(kind), class: kind, title: kind) }
|
43
|
+
[content_tag(:th, analyser.class.human_name, class: type),
|
44
|
+
content_tag(:td, "#{f[:executed]} #{f[:ignored] if data.ignored > 0} / #{f[:potentially_executable]}", class: type),
|
45
|
+
]
|
46
|
+
end
|
47
|
+
rows = cells.transpose.map { |line| content_tag(:tr, line.join) }
|
48
|
+
content_tag(:table, rows.join)
|
49
|
+
end
|
50
|
+
|
51
|
+
def analyser
|
52
|
+
analyser_map[:per_char]
|
53
|
+
end
|
54
|
+
|
55
|
+
def covered_code
|
56
|
+
analyser.covered_code
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
RUNS_CLASS = Hash.new('run').merge!(0 => 'not-run', nil => 'ignored')
|
62
|
+
RUNS_TITLE = Hash.new { |k, runs| "#{runs}x" }.merge!(0 => 'never run', nil => 'ignored')
|
63
|
+
|
64
|
+
def node_span(node, kind)
|
65
|
+
runs = analyser.node_runs(node)
|
66
|
+
%{<span class="node-#{node.type} kind-#{kind} #{RUNS_CLASS[runs]}" title="#{RUNS_TITLE[runs]}">}
|
67
|
+
end
|
68
|
+
|
69
|
+
def insert_node_tags
|
70
|
+
analyser.each_node do |node|
|
71
|
+
h = node.executed_loc_hash
|
72
|
+
h.each do |kind, range|
|
73
|
+
wrap(range, node_span(node, kind), '</span>')
|
74
|
+
end
|
75
|
+
exp = node.expression
|
76
|
+
if (exp.nil? || exp.empty?) && !analyser.node_covered?(node) && !node.parent.is_a?(Node::Branch) # Not executed empty bodies must show!
|
77
|
+
replace(exp, icon(:empty, 'empty node never run'))
|
78
|
+
wrap(exp, node_span(node, :empty))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
ICONS = {
|
84
|
+
fork: 'code-fork',
|
85
|
+
empty: 'code',
|
86
|
+
}.freeze
|
87
|
+
def icon(type, title)
|
88
|
+
%{<i class="#{type}-icon fa fa-#{ICONS[type]}" aria-hidden="true" title="#{title}"></i>}
|
89
|
+
end
|
90
|
+
|
91
|
+
def fork_span(node, kind, id, title: nil, klass: nil)
|
92
|
+
runs = analyser_map[:branch].node_runs(node)
|
93
|
+
title ||= RUNS_TITLE[runs]
|
94
|
+
%{<span class="fork fork-#{kind} fork-#{RUNS_CLASS[runs]} #{klass}" data-fork-id="#{id}">#{icon(:fork, title)}}
|
95
|
+
end
|
96
|
+
|
97
|
+
def insert_branch_tags
|
98
|
+
analyser_map[:branch].each_node.with_index do |node, id|
|
99
|
+
node.branches.each do |branch|
|
100
|
+
exp = branch.expression
|
101
|
+
wrap(exp, fork_span(branch, :branch, id), '</span>') if exp
|
102
|
+
end
|
103
|
+
runs = analyser_map[:branch].node_runs(node)
|
104
|
+
if !covered?(runs) && analyser.node_covered?(node)
|
105
|
+
jumps_missing = node.branches.reject { |jump| analyser.node_covered?(jump) }
|
106
|
+
title = "#{node.branches_summary(jumps_missing)} not covered"
|
107
|
+
klass = 'fork-with-uncovered-branches'
|
108
|
+
end
|
109
|
+
wrap(node.expression, fork_span(node, :whole, id, title: title, klass: klass))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def replace(range, with)
|
114
|
+
@rewriter.replace(range, with) rescue binding.pry
|
115
|
+
end
|
116
|
+
|
117
|
+
def wrap(range, before, after = '</span>')
|
118
|
+
line = @rewriter.source_buffer.line_range(range.first_line)
|
119
|
+
pinned = range.with(end_pos: [range, line].map(&:end_pos).min)
|
120
|
+
@rewriter.wrap(pinned, before, after) rescue binding.pry
|
121
|
+
end
|
122
|
+
|
123
|
+
def html_escape
|
124
|
+
buffer = analyser.covered_code.buffer
|
125
|
+
source = buffer.source
|
126
|
+
{'<' => '<', '>' => '>', '&' => '&'}.each do |char, escaped|
|
127
|
+
source.scan(char) do
|
128
|
+
m = Regexp.last_match
|
129
|
+
range = ::Parser::Source::Range.new(buffer, m.begin(0), m.end(0))
|
130
|
+
@rewriter.replace(range, escaped)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,338 @@
|
|
1
|
+
// Adapted from GitHub's scheme https://raw.githubusercontent.com/primer/github-syntax-light/master/lib/github-light.css
|
2
|
+
$pl-c: #6a737d /* comment punctuation.definition.comment string.comment */
|
3
|
+
|
4
|
+
/* constant entity.name.constant variable.other.constant variable.language support meta.property-name support.constant support.variable meta.module-reference markup.raw meta.diff.header meta.output */
|
5
|
+
$pl-c1: #005cc5 /* string variable */
|
6
|
+
|
7
|
+
$pl-en: #6f42c1 /* entity.name */
|
8
|
+
|
9
|
+
/* variable.parameter.function storage.modifier.package storage.modifier.import storage.type.java variable.other */
|
10
|
+
$pl-s1: #24292e /* string source */
|
11
|
+
|
12
|
+
|
13
|
+
$pl-ent: #22863a /* entity.name.tag markup.quote */
|
14
|
+
|
15
|
+
|
16
|
+
$pl-k: #d73a49 /* keyword storage storage.type */
|
17
|
+
$pl-k: #a419ea /* override */
|
18
|
+
|
19
|
+
/* string */
|
20
|
+
/* punctuation.definition.string source.regexp string.regexp.character-class */
|
21
|
+
/* string punctuation.section.embedded source */
|
22
|
+
/* string.regexp */
|
23
|
+
/* string.regexp constant.character.escape */
|
24
|
+
/* string.regexp source.ruby.embedded */
|
25
|
+
$pl-s: #032f62 /* string.regexp string.regexp.arbitrary-repitition */
|
26
|
+
|
27
|
+
/* variable */
|
28
|
+
$pl-v: #e36209 /* sublimelinter.mark.warning */
|
29
|
+
|
30
|
+
$pl-bu: #b31d28 /* invalid.broken invalid.deprecated invalid.unimplemented message.error brackethighlighter.unmatched sublimelinter.mark.error */
|
31
|
+
|
32
|
+
$pl-ii: #fafbfc /* invalid.illegal */
|
33
|
+
$pl-ii-background: #b31d28
|
34
|
+
|
35
|
+
$pl-sr: #22863a /* string.regexp constant.character.escape */
|
36
|
+
|
37
|
+
$pl-ml: #735c0f /* markup.list */
|
38
|
+
|
39
|
+
/* markup.heading */
|
40
|
+
/* markup.heading entity.name */
|
41
|
+
$pl-mh: #005cc5 /* meta.separator */
|
42
|
+
|
43
|
+
$pl-mi2: #f6f8fa /* markup.ignored markup.untracked */
|
44
|
+
$pl-mi2-background: #005cc5
|
45
|
+
|
46
|
+
|
47
|
+
// http://meyerweb.com/eric/tools/css/reset/
|
48
|
+
// v2.0 | 20110126
|
49
|
+
// License: none (public domain)
|
50
|
+
|
51
|
+
|
52
|
+
html, body, div, span, applet, object, iframe,
|
53
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
54
|
+
a, abbr, acronym, address, big, cite, code,
|
55
|
+
del, dfn, em, img, ins, kbd, q, s, samp,
|
56
|
+
small, strike, strong, sub, sup, tt, var,
|
57
|
+
b, u, i, center,
|
58
|
+
dl, dt, dd, ol, ul, li,
|
59
|
+
fieldset, form, label, legend,
|
60
|
+
table, caption, tbody, tfoot, thead, tr, th, td,
|
61
|
+
article, aside, canvas, details, embed,
|
62
|
+
figure, figcaption, footer, header, hgroup,
|
63
|
+
menu, nav, output, ruby, section, summary,
|
64
|
+
time, mark, audio, video
|
65
|
+
margin: 0
|
66
|
+
padding: 0
|
67
|
+
border: 0
|
68
|
+
font-size: 100%
|
69
|
+
// font: inherit
|
70
|
+
vertical-align: baseline
|
71
|
+
|
72
|
+
// HTML5 display-role reset for older browsers
|
73
|
+
article, aside, details, figcaption, figure,
|
74
|
+
footer, header, hgroup, menu, nav, section
|
75
|
+
display: block
|
76
|
+
|
77
|
+
body
|
78
|
+
line-height: 1
|
79
|
+
|
80
|
+
ol, ul
|
81
|
+
list-style: none
|
82
|
+
|
83
|
+
blockquote, q
|
84
|
+
quotes: none
|
85
|
+
|
86
|
+
blockquote:before, blockquote:after,
|
87
|
+
q:before, q:after
|
88
|
+
content: ''
|
89
|
+
content: none
|
90
|
+
|
91
|
+
table
|
92
|
+
border-collapse: collapse
|
93
|
+
border-spacing: 0
|
94
|
+
|
95
|
+
|
96
|
+
// Global settings
|
97
|
+
*
|
98
|
+
box-sizing: border-box
|
99
|
+
border-collapse: collapse
|
100
|
+
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif
|
101
|
+
|
102
|
+
// *** DeepCover Source ***
|
103
|
+
|
104
|
+
$dark-green: #25712b
|
105
|
+
$light-green: #74b770
|
106
|
+
$light-gray: #e1e4e8
|
107
|
+
|
108
|
+
%light-border
|
109
|
+
border: 1px solid $light-gray
|
110
|
+
|
111
|
+
.fork-branch > .fork-icon
|
112
|
+
display: none
|
113
|
+
%show-fork-icon
|
114
|
+
.fork-branch > .fork-icon
|
115
|
+
display: inherit
|
116
|
+
%center
|
117
|
+
width: 980px
|
118
|
+
margin: 0 auto 0 auto
|
119
|
+
|
120
|
+
$toggled: $light-green
|
121
|
+
$not-run: hsl(hue(#f00), 100%, 85%)
|
122
|
+
$ignored: hsl(0, 0, 85%)
|
123
|
+
|
124
|
+
// *** Common template ***
|
125
|
+
main
|
126
|
+
@extend %center
|
127
|
+
padding-top: 10px
|
128
|
+
.overlay
|
129
|
+
width: 100%
|
130
|
+
position: fixed
|
131
|
+
top: 0
|
132
|
+
z-index: 9999
|
133
|
+
.center
|
134
|
+
position: relative
|
135
|
+
@extend %center
|
136
|
+
|
137
|
+
header
|
138
|
+
width: 100%
|
139
|
+
position: relative
|
140
|
+
top: 0
|
141
|
+
background: #24292e
|
142
|
+
color: rgba(255,255,255,0.75)
|
143
|
+
padding-bottom: 4px
|
144
|
+
|
145
|
+
.content
|
146
|
+
position: relative
|
147
|
+
@extend %center
|
148
|
+
|
149
|
+
.info
|
150
|
+
padding: 4px 0 4px 0
|
151
|
+
color: #88d483
|
152
|
+
.deep-cover
|
153
|
+
transition: opacity 0.4s
|
154
|
+
opacity: 0.3
|
155
|
+
font-size: 24px
|
156
|
+
font-weight: 900
|
157
|
+
.deep
|
158
|
+
color: #74b770
|
159
|
+
.version
|
160
|
+
transition: opacity 0.4s
|
161
|
+
opacity: 0.1
|
162
|
+
font-size: 12px
|
163
|
+
font-weight: lighter
|
164
|
+
&:hover
|
165
|
+
.deep-cover
|
166
|
+
opacity: 0.8
|
167
|
+
.version
|
168
|
+
opacity: 0.6
|
169
|
+
|
170
|
+
// *** DeepCover Source ***
|
171
|
+
body.source &
|
172
|
+
.nav
|
173
|
+
a
|
174
|
+
color: white
|
175
|
+
body.source
|
176
|
+
.stats
|
177
|
+
th, td
|
178
|
+
padding: 6px
|
179
|
+
border-right: 1px solid $light-gray
|
180
|
+
td
|
181
|
+
padding-top: 0
|
182
|
+
table
|
183
|
+
@extend %light-border
|
184
|
+
position: absolute
|
185
|
+
background: white
|
186
|
+
right: 20px
|
187
|
+
top: 15px
|
188
|
+
color: $pl-s
|
189
|
+
.ignored
|
190
|
+
opacity: 0.7
|
191
|
+
&::before
|
192
|
+
content: "[+"
|
193
|
+
&::after
|
194
|
+
content: "]"
|
195
|
+
|
196
|
+
main
|
197
|
+
white-space: pre
|
198
|
+
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace
|
199
|
+
font-size: 12px
|
200
|
+
line-height: 20px
|
201
|
+
|
202
|
+
table.source
|
203
|
+
@extend %light-border
|
204
|
+
width: 100%
|
205
|
+
|
206
|
+
td
|
207
|
+
vertical-align: top
|
208
|
+
|
209
|
+
.nb
|
210
|
+
color: rgba(27,31,35,0.3)
|
211
|
+
text-align: right
|
212
|
+
width: 50px
|
213
|
+
padding-right: 10px
|
214
|
+
padding-left: 10px
|
215
|
+
// * Color scheme *
|
216
|
+
|
217
|
+
// Default color, for unexecutable code
|
218
|
+
color: $pl-c
|
219
|
+
|
220
|
+
// Executed code
|
221
|
+
.run
|
222
|
+
color: $pl-s
|
223
|
+
|
224
|
+
.not-run
|
225
|
+
background-color: $not-run
|
226
|
+
padding: 2px 0
|
227
|
+
|
228
|
+
.ignored
|
229
|
+
background-color: $ignored
|
230
|
+
padding: 2px 0
|
231
|
+
|
232
|
+
.kind-keyword, .kind-else
|
233
|
+
color: $pl-k
|
234
|
+
|
235
|
+
.node-def.kind-name
|
236
|
+
color: #3e920c
|
237
|
+
|
238
|
+
// Literals:
|
239
|
+
.kind-expression, .node-const
|
240
|
+
color: $pl-c1
|
241
|
+
|
242
|
+
.node-send
|
243
|
+
color: $dark-green
|
244
|
+
|
245
|
+
.node-str
|
246
|
+
color: $pl-s
|
247
|
+
|
248
|
+
// Icons
|
249
|
+
.icon-not-run
|
250
|
+
background-color: $not-run
|
251
|
+
border-color: red
|
252
|
+
.icon-ignored
|
253
|
+
background-color: $ignored
|
254
|
+
border-color: darken($ignored, 20%)
|
255
|
+
.icon
|
256
|
+
position: absolute
|
257
|
+
left: -2.2ex
|
258
|
+
width: 2ex
|
259
|
+
height: 1.5em
|
260
|
+
line-height: 1.5em
|
261
|
+
text-align: center
|
262
|
+
background-color: white
|
263
|
+
padding: 0
|
264
|
+
@extend %light-border
|
265
|
+
|
266
|
+
.kind-empty
|
267
|
+
position: relative
|
268
|
+
& > .empty-icon
|
269
|
+
@extend .icon
|
270
|
+
left: -2.5ex
|
271
|
+
width: 2.3ex
|
272
|
+
&.not-run > .empty-icon
|
273
|
+
@extend .icon-not-run
|
274
|
+
|
275
|
+
// Branches
|
276
|
+
.fork
|
277
|
+
position: relative
|
278
|
+
.fork-icon
|
279
|
+
@extend .icon
|
280
|
+
.fork-whole
|
281
|
+
& > .fork-icon
|
282
|
+
z-index: 1
|
283
|
+
&:hover
|
284
|
+
@extend %show-fork-icon
|
285
|
+
background: $light-gray
|
286
|
+
padding: 2px 0
|
287
|
+
|
288
|
+
.fork-with-uncovered-branches
|
289
|
+
&.fork-not-run > .fork-icon
|
290
|
+
@extend .icon-not-run
|
291
|
+
&.fork-ignored > .fork-icon
|
292
|
+
@extend .icon-ignored
|
293
|
+
|
294
|
+
&.show-forks
|
295
|
+
@extend %show-fork-icon
|
296
|
+
.fork-whole
|
297
|
+
background: $light-gray
|
298
|
+
.stats .branch
|
299
|
+
background: $toggled
|
300
|
+
|
301
|
+
// *** Index ***
|
302
|
+
|
303
|
+
.tree
|
304
|
+
// Overrides
|
305
|
+
.jstree-table-cell
|
306
|
+
padding-left: 0
|
307
|
+
span
|
308
|
+
padding-right: 4px
|
309
|
+
.jstree-table-header-cell
|
310
|
+
// Leave space for sort arrows:
|
311
|
+
padding-right: 17px
|
312
|
+
font-style: italic
|
313
|
+
.jstree-table-sort-icon
|
314
|
+
right: 4px
|
315
|
+
top: 8px
|
316
|
+
left: inherit
|
317
|
+
.jstree-table-separator
|
318
|
+
border: none
|
319
|
+
|
320
|
+
.jstree-table-column
|
321
|
+
text-align: right
|
322
|
+
border: gray 1px #ddd
|
323
|
+
.jstree-table-column-0
|
324
|
+
text-align: left
|
325
|
+
|
326
|
+
.percent-100
|
327
|
+
color: green
|
328
|
+
.percent-90
|
329
|
+
color: blue
|
330
|
+
.percent-80
|
331
|
+
color: brown
|
332
|
+
.percent-60, .percent-70
|
333
|
+
color: orange
|
334
|
+
.percent-00, .percent-10, .percent-20, .percent-30, .percent-40, .percent-50
|
335
|
+
color: red
|
336
|
+
|
337
|
+
footer
|
338
|
+
display: none
|