Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F95373669
index.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Dec 15, 03:52
Size
14 KB
Mime Type
text/html
Expires
Tue, Dec 17, 03:52 (1 d, 21 h)
Engine
blob
Format
Raw Data
Handle
22963849
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
index.js
View Options
'use strict'
;
/*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
const
fs
=
require
(
'fs'
);
const
path
=
require
(
'path'
);
const
html
=
require
(
'html-escaper'
);
const
{
ReportBase
}
=
require
(
'istanbul-lib-report'
);
const
annotator
=
require
(
'./annotator'
);
function
htmlHead
(
details
)
{
return
`
<
head
>
<
title
>
Code
coverage
report
for
$
{
html
.
escape
(
details
.
entity
)}
<
/title>
<
meta
charset
=
"utf-8"
/>
<
link
rel
=
"stylesheet"
href
=
"${html.escape(details.prettify.css)}"
/>
<
link
rel
=
"stylesheet"
href
=
"${html.escape(details.base.css)}"
/>
<
link
rel
=
"shortcut icon"
type
=
"image/x-icon"
href
=
"${html.escape(
details.favicon
)}"
/>
<
meta
name
=
"viewport"
content
=
"width=device-width, initial-scale=1"
/>
<
style
type
=
'text/css'
>
.
coverage
-
summary
.
sorter
{
background
-
image
:
url
(
$
{
html
.
escape
(
details
.
sorter
.
image
)});
}
<
/style>
<
/head>
`
;
}
function
headerTemplate
(
details
)
{
function
metricsTemplate
({
pct
,
covered
,
total
},
kind
)
{
return
`
<
div
class
=
'fl pad1y space-right2'
>
<
span
class
=
"strong"
>
$
{
pct
}
%
<
/span>
<
span
class
=
"quiet"
>
$
{
kind
}
<
/span>
<
span
class
=
'fraction'
>
$
{
covered
}
/
$
{
total
}
<
/span>
<
/div>
`
;
}
function
skipTemplate
(
metrics
)
{
const
statements
=
metrics
.
statements
.
skipped
;
const
branches
=
metrics
.
branches
.
skipped
;
const
functions
=
metrics
.
functions
.
skipped
;
const
countLabel
=
(
c
,
label
,
plural
)
=>
c
===
0
?
[]
:
`
$
{
c
}
$
{
label
}
$
{
c
===
1
?
''
:
plural
}
`
;
const
skips
=
[].
concat
(
countLabel
(
statements
,
'statement'
,
's'
),
countLabel
(
functions
,
'function'
,
's'
),
countLabel
(
branches
,
'branch'
,
'es'
)
);
if
(
skips
.
length
===
0
)
{
return
''
;
}
return
`
<
div
class
=
'fl pad1y'
>
<
span
class
=
"strong"
>
$
{
skips
.
join
(
', '
)}
<
/span>
<
span
class
=
"quiet"
>
Ignored
<
/span>
<
/div>
`
;
}
return
`
<!
doctype
html
>
<
html
lang
=
"en"
>
$
{
htmlHead
(
details
)}
<
body
>
<
div
class
=
'wrapper'
>
<
div
class
=
'pad1'
>
<
h1
>
$
{
details
.
pathHtml
}
<
/h1>
<
div
class
=
'clearfix'
>
$
{
metricsTemplate
(
details
.
metrics
.
statements
,
'Statements'
)}
$
{
metricsTemplate
(
details
.
metrics
.
branches
,
'Branches'
)}
$
{
metricsTemplate
(
details
.
metrics
.
functions
,
'Functions'
)}
$
{
metricsTemplate
(
details
.
metrics
.
lines
,
'Lines'
)}
$
{
skipTemplate
(
details
.
metrics
)}
<
/div>
<
p
class
=
"quiet"
>
Press
<
em
>
n
<
/em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
<
/p>
<
template
id
=
"filterTemplate"
>
<
div
class
=
"quiet"
>
Filter
:
<
input
oninput
=
"onInput()"
type
=
"search"
id
=
"fileSearch"
>
<
/div>
<
/template>
<
/div>
<
div
class
=
'status-line ${details.reportClass}'
><
/div>
`
;
}
function
footerTemplate
(
details
)
{
return
`
<
div
class
=
'push'
><
/div><!-- for sticky footer -->
<
/div><!-- /wrapper -->
<
div
class
=
'footer quiet pad2 space-top1 center small'
>
Code
coverage
generated
by
<
a
href
=
"https://istanbul.js.org/"
target
=
"_blank"
rel
=
"noopener noreferrer"
>
istanbul
<
/a>
at
$
{
html
.
escape
(
details
.
datetime
)}
<
/div>
<
script
src
=
"${html.escape(details.prettify.js)}"
><
/script>
<
script
>
window
.
onload
=
function
()
{
prettyPrint
();
};
<
/script>
<
script
src
=
"${html.escape(details.sorter.js)}"
><
/script>
<
script
src
=
"${html.escape(details.blockNavigation.js)}"
><
/script>
<
/body>
<
/html>
`
;
}
function
detailTemplate
(
data
)
{
const
lineNumbers
=
new
Array
(
data
.
maxLines
).
fill
().
map
((
_
,
i
)
=>
i
+
1
);
const
lineLink
=
num
=>
`
<
a
name
=
'L${num}'
><
/a><a href='#L${num}'>${num}</a>`;
const
lineCount
=
line
=>
`
<
span
class
=
"cline-any cline-${line.covered}"
>
$
{
line
.
hits
}
<
/span>`;
/* This is rendered in a `<pre>`, need control of all whitespace. */
return
[
'<tr>'
,
`
<
td
class
=
"line-count quiet"
>
$
{
lineNumbers
.
map
(
lineLink
)
.
join
(
'\n'
)}
<
/td>`,
`
<
td
class
=
"line-coverage quiet"
>
$
{
data
.
lineCoverage
.
map
(
lineCount
)
.
join
(
'\n'
)}
<
/td>`,
`
<
td
class
=
"text"
><
pre
class
=
"prettyprint lang-js"
>
$
{
data
.
annotatedCode
.
join
(
'\n'
)}
<
/pre></td>`,
'</tr>'
].
join
(
''
);
}
const
summaryTableHeader
=
[
'<div class="pad1">'
,
'<table class="coverage-summary">'
,
'<thead>'
,
'<tr>'
,
' <th data-col="file" data-fmt="html" data-html="true" class="file">File</th>'
,
' <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>'
,
' <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>'
,
' <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>'
,
' <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>'
,
' <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>'
,
' <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>'
,
' <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>'
,
' <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>'
,
' <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>'
,
'</tr>'
,
'</thead>'
,
'<tbody>'
].
join
(
'\n'
);
function
summaryLineTemplate
(
details
)
{
const
{
reportClasses
,
metrics
,
file
,
output
}
=
details
;
const
percentGraph
=
pct
=>
{
if
(
!
isFinite
(
pct
))
{
return
''
;
}
const
cls
=
[
'cover-fill'
];
if
(
pct
===
100
)
{
cls
.
push
(
'cover-full'
);
}
pct
=
Math
.
floor
(
pct
);
return
[
`
<
div
class
=
"${cls.join(' ')}"
style
=
"width: ${pct}%"
><
/div>`,
`
<
div
class
=
"cover-empty"
style
=
"width: ${100 - pct}%"
><
/div>`
].
join
(
''
);
};
const
summaryType
=
(
type
,
showGraph
=
false
)
=>
{
const
info
=
metrics
[
type
];
const
reportClass
=
reportClasses
[
type
];
const
result
=
[
`
<
td
data
-
value
=
"${info.pct}"
class
=
"pct ${reportClass}"
>
$
{
info
.
pct
}
%<
/td>`,
`
<
td
data
-
value
=
"${info.total}"
class
=
"abs ${reportClass}"
>
$
{
info
.
covered
}
/
$
{
info
.
total
}
<
/td>`
];
if
(
showGraph
)
{
result
.
unshift
(
`
<
td
data
-
value
=
"${info.pct}"
class
=
"pic ${reportClass}"
>
`
,
`
<
div
class
=
"chart"
>
$
{
percentGraph
(
info
.
pct
)}
<
/div>`,
`
<
/td>`
);
}
return
result
;
};
return
[]
.
concat
(
'<tr>'
,
`
<
td
class
=
"file ${
reportClasses.statements
}"
data
-
value
=
"${html.escape(file)}"
><
a
href
=
"${html.escape(
output
)}"
>
$
{
html
.
escape
(
file
)}
<
/a></td>`,
summaryType
(
'statements'
,
true
),
summaryType
(
'branches'
),
summaryType
(
'functions'
),
summaryType
(
'lines'
),
'</tr>\n'
)
.
join
(
'\n\t'
);
}
const
summaryTableFooter
=
[
'</tbody>'
,
'</table>'
,
'</div>'
].
join
(
'\n'
);
const
emptyClasses
=
{
statements
:
'empty'
,
lines
:
'empty'
,
functions
:
'empty'
,
branches
:
'empty'
};
const
standardLinkMapper
=
{
getPath
(
node
)
{
if
(
typeof
node
===
'string'
)
{
return
node
;
}
let
filePath
=
node
.
getQualifiedName
();
if
(
node
.
isSummary
())
{
if
(
filePath
!==
''
)
{
filePath
+=
'/index.html'
;
}
else
{
filePath
=
'index.html'
;
}
}
else
{
filePath
+=
'.html'
;
}
return
filePath
;
},
relativePath
(
source
,
target
)
{
const
targetPath
=
this
.
getPath
(
target
);
const
sourcePath
=
path
.
dirname
(
this
.
getPath
(
source
));
return
path
.
posix
.
relative
(
sourcePath
,
targetPath
);
},
assetPath
(
node
,
name
)
{
return
this
.
relativePath
(
this
.
getPath
(
node
),
name
);
}
};
function
fixPct
(
metrics
)
{
Object
.
keys
(
emptyClasses
).
forEach
(
key
=>
{
metrics
[
key
].
pct
=
0
;
});
return
metrics
;
}
class
HtmlReport
extends
ReportBase
{
constructor
(
opts
)
{
super
();
this
.
verbose
=
opts
.
verbose
;
this
.
linkMapper
=
opts
.
linkMapper
||
standardLinkMapper
;
this
.
subdir
=
opts
.
subdir
||
''
;
this
.
date
=
new
Date
().
toISOString
();
this
.
skipEmpty
=
opts
.
skipEmpty
;
}
getBreadcrumbHtml
(
node
)
{
let
parent
=
node
.
getParent
();
const
nodePath
=
[];
while
(
parent
)
{
nodePath
.
push
(
parent
);
parent
=
parent
.
getParent
();
}
const
linkPath
=
nodePath
.
map
(
ancestor
=>
{
const
target
=
this
.
linkMapper
.
relativePath
(
node
,
ancestor
);
const
name
=
ancestor
.
getRelativeName
()
||
'All files'
;
return
'<a href="'
+
target
+
'">'
+
name
+
'</a>'
;
});
linkPath
.
reverse
();
return
linkPath
.
length
>
0
?
linkPath
.
join
(
' / '
)
+
' '
+
node
.
getRelativeName
()
:
'All files'
;
}
fillTemplate
(
node
,
templateData
,
context
)
{
const
linkMapper
=
this
.
linkMapper
;
const
summary
=
node
.
getCoverageSummary
();
templateData
.
entity
=
node
.
getQualifiedName
()
||
'All files'
;
templateData
.
metrics
=
summary
;
templateData
.
reportClass
=
context
.
classForPercent
(
'statements'
,
summary
.
statements
.
pct
);
templateData
.
pathHtml
=
this
.
getBreadcrumbHtml
(
node
);
templateData
.
base
=
{
css
:
linkMapper
.
assetPath
(
node
,
'base.css'
)
};
templateData
.
sorter
=
{
js
:
linkMapper
.
assetPath
(
node
,
'sorter.js'
),
image
:
linkMapper
.
assetPath
(
node
,
'sort-arrow-sprite.png'
)
};
templateData
.
blockNavigation
=
{
js
:
linkMapper
.
assetPath
(
node
,
'block-navigation.js'
)
};
templateData
.
prettify
=
{
js
:
linkMapper
.
assetPath
(
node
,
'prettify.js'
),
css
:
linkMapper
.
assetPath
(
node
,
'prettify.css'
)
};
templateData
.
favicon
=
linkMapper
.
assetPath
(
node
,
'favicon.png'
);
}
getTemplateData
()
{
return
{
datetime
:
this
.
date
};
}
getWriter
(
context
)
{
if
(
!
this
.
subdir
)
{
return
context
.
writer
;
}
return
context
.
writer
.
writerForDir
(
this
.
subdir
);
}
onStart
(
root
,
context
)
{
const
assetHeaders
=
{
'.js'
:
'/* eslint-disable */\n'
};
[
'.'
,
'vendor'
].
forEach
(
subdir
=>
{
const
writer
=
this
.
getWriter
(
context
);
const
srcDir
=
path
.
resolve
(
__dirname
,
'assets'
,
subdir
);
fs
.
readdirSync
(
srcDir
).
forEach
(
f
=>
{
const
resolvedSource
=
path
.
resolve
(
srcDir
,
f
);
const
resolvedDestination
=
'.'
;
const
stat
=
fs
.
statSync
(
resolvedSource
);
let
dest
;
if
(
stat
.
isFile
())
{
dest
=
resolvedDestination
+
'/'
+
f
;
if
(
this
.
verbose
)
{
console
.
log
(
'Write asset: '
+
dest
);
}
writer
.
copyFile
(
resolvedSource
,
dest
,
assetHeaders
[
path
.
extname
(
f
)]
);
}
});
});
}
onSummary
(
node
,
context
)
{
const
linkMapper
=
this
.
linkMapper
;
const
templateData
=
this
.
getTemplateData
();
const
children
=
node
.
getChildren
();
const
skipEmpty
=
this
.
skipEmpty
;
this
.
fillTemplate
(
node
,
templateData
,
context
);
const
cw
=
this
.
getWriter
(
context
).
writeFile
(
linkMapper
.
getPath
(
node
));
cw
.
write
(
headerTemplate
(
templateData
));
cw
.
write
(
summaryTableHeader
);
children
.
forEach
(
child
=>
{
const
metrics
=
child
.
getCoverageSummary
();
const
isEmpty
=
metrics
.
isEmpty
();
if
(
skipEmpty
&&
isEmpty
)
{
return
;
}
const
reportClasses
=
isEmpty
?
emptyClasses
:
{
statements
:
context
.
classForPercent
(
'statements'
,
metrics
.
statements
.
pct
),
lines
:
context
.
classForPercent
(
'lines'
,
metrics
.
lines
.
pct
),
functions
:
context
.
classForPercent
(
'functions'
,
metrics
.
functions
.
pct
),
branches
:
context
.
classForPercent
(
'branches'
,
metrics
.
branches
.
pct
)
};
const
data
=
{
metrics
:
isEmpty
?
fixPct
(
metrics
)
:
metrics
,
reportClasses
,
file
:
child
.
getRelativeName
(),
output
:
linkMapper
.
relativePath
(
node
,
child
)
};
cw
.
write
(
summaryLineTemplate
(
data
)
+
'\n'
);
});
cw
.
write
(
summaryTableFooter
);
cw
.
write
(
footerTemplate
(
templateData
));
cw
.
close
();
}
onDetail
(
node
,
context
)
{
const
linkMapper
=
this
.
linkMapper
;
const
templateData
=
this
.
getTemplateData
();
this
.
fillTemplate
(
node
,
templateData
,
context
);
const
cw
=
this
.
getWriter
(
context
).
writeFile
(
linkMapper
.
getPath
(
node
));
cw
.
write
(
headerTemplate
(
templateData
));
cw
.
write
(
'<pre><table class="coverage">\n'
);
cw
.
write
(
detailTemplate
(
annotator
(
node
.
getFileCoverage
(),
context
)));
cw
.
write
(
'</table></pre>\n'
);
cw
.
write
(
footerTemplate
(
templateData
));
cw
.
close
();
}
}
module
.
exports
=
HtmlReport
;
Event Timeline
Log In to Comment