Skip to content

Commit

Permalink
Updated HTML Reporter
Browse files Browse the repository at this point in the history
  • Loading branch information
Johnykutty Mathew committed Nov 1, 2016
1 parent a6ce574 commit af7404a
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 29 deletions.
114 changes: 87 additions & 27 deletions Source/SwiftLintFramework/Reporters/HTMLReporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,66 +12,126 @@ public struct HTMLReporter: Reporter {
public static let isRealtime = false

public var description: String {
return "Reports violations as Checkstyle XML."
return "Reports violations as HTML"
}

// swiftlint:disable function_body_length
public static func generateReport(violations: [StyleViolation]) -> String {
// swiftlint:enable function_body_length
var rows = ""
for (index, violation) in violations.enumerate() {
rows += generateSingleRow(for: violation, at: index + 1)
}
var HTML = HTMLTemplate()
HTML = HTML.stringByReplacingOccurrencesOfString("__table_rows__", withString: rows)

let bundle = NSBundle(identifier: "io.realm.SwiftLintFramework")!
let version = bundle.objectForInfoDictionaryKey("CFBundleShortVersionString")
let v = (version as? String ?? "0.0.0")
HTML = HTML.stringByReplacingOccurrencesOfString("__version__", withString: v)

let files = violations.map { violation in
violation.location.file ?? ""
}
let uniqueFiles = Set(files)
var countKey = "__number_of_files__"
var count = "\(uniqueFiles.count)"
HTML = HTML.stringByReplacingOccurrencesOfString(countKey, withString: count)

let warnings = violations.filter { violation in
violation.severity == .Warning
}
countKey = "__number_of_warnings__"
count = "\(warnings.count)"
HTML = HTML.stringByReplacingOccurrencesOfString(countKey, withString: count)

let errors = violations.filter { violation in
violation.severity == .Error
}
countKey = "__number_of_errors__"
count = "\(errors.count)"
HTML = HTML.stringByReplacingOccurrencesOfString(countKey, withString: count)

let formatter = NSDateFormatter()
formatter.dateStyle = .ShortStyle
let dateString = formatter.stringFromDate(NSDate())
HTML = HTML.stringByReplacingOccurrencesOfString("__report_date__", withString: dateString)

return HTML
return "<!doctype html>\n" +
"<html>\n" +
"\t<head>\n" +
"\t\t<title>Swiftlint Report</title>\n" +
"\t\t<style type='text/css'>\n" +
"\t\t\ttable {\n" +
"\t\t\t\tborder: 1px solid gray;\n" +
"\t\t\t\tborder-collapse: collapse;\n" +
"\t\t\t\t-moz-box-shadow: 3px 3px 4px #AAA;\n" +
"\t\t\t\t-webkit-box-shadow: 3px 3px 4px #AAA;\n" +
"\t\t\t\tbox-shadow: 3px 3px 4px #AAA;\n" +
"\t\t\t}\n" +
"\t\ttd, th {\n" +
"\t\t\t\tborder: 1px solid #D3D3D3;\n" +
"\t\t\t\tpadding: 5px 10px 5px 10px;\n" +
"\t\t}\n" +
"\t\tth {\n" +
"\t\t\tborder-bottom: 1px solid gray;\n" +
"\t\t\tbackground-color: #29345C50;\n" +
"\t\t}\n" +
"\t\t.error, .warning {\n" +
"\t\t\tbackground-color: #f0f099;\n" +
"\t\t} .error{ color: #ff0000;}\n" +
"\t\t.warning { color: #b36b00;\n" +
"\t\t}\n" +
"\t\t</style>\n" +
"\t</head>\n" +
"\t<body>\n" +
"\t\t<h1>Swiftlint Report</h1>\n" +
"\t\t<hr />\n" +
"\t\t<h2>Violations</h2>\n" +
"\t\t<table border=\"1\" style=\"vertical-align: top; height: 64px;\">\n" +
"\t\t\t<thead>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<th style=\"width: 60pt;\">\n" +
"\t\t\t\t\t\t<b>Serial No.</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 500pt;\">\n" +
"\t\t\t\t\t\t<b>File</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 60pt;\">\n" +
"\t\t\t\t\t\t<b>Location</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 60pt;\">\n" +
"\t\t\t\t\t\t<b>Severity</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 500pt;\">\n" +
"\t\t\t\t\t\t<b>Message</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t</thead>\n" +
"\t\t\t<tbody>\n" + rows + "\t\t\t</tbody>\n" +
"\t\t</table>\n" +
"\t\t<br/>\n" +
"\t\t<h2>Summary</h2>\n" +
"\t\t<table border=\"1\" style=\"vertical-align: top; height: 64px;\">\n" +
"\t\t\t<tbody>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td>Total files with violations</td>\n" +
"\t\t\t\t\t<td>\(uniqueFiles.count)</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td>Total warnings</td>\n" +
"\t\t\t\t\t<td>\(warnings.count)</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td>Total errors</td>\n" +
"\t\t\t\t\t<td>\(errors.count)</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t</tbody>\n" +
"\t\t</table>\n" +
"\t\t<hr />\n" +
"\t\t<p>Created with <a href=\"https://github.com/realm/SwiftLint\">\n" +
"\t\t\t<b>Swiftlint</b>\n" +
"\t\t</a> " + v + " on: " + dateString + "</p>\n" +
"\t</body>\n" +
"</html>"
}

private static func generateSingleRow(for violation: StyleViolation, at index: Int) -> String {
let severity = violation.severity.rawValue
let location = violation.location
return "<tr>" +
"<td align=\"right\">\(index)</td>" +
"<td>\(location.file ?? "")</td>" +
"<td align=\"center\">\(location.line ?? 0):\(location.character ?? 0)</td>" +
"<td class=\'\(severity.lowercaseString)\'>\(severity) </td>" +
"<td>\(violation.reason)</td>" +
"</tr>"
}

private static func HTMLTemplate() -> String {

return "<!doctype html><html><head><title>Swiftlint Report</title><style type='text/css'>table { border: 1px solid gray; border-collapse: collapse; -moz-box-shadow: 3px 3px 4px #AAA; -webkit-box-shadow: 3px 3px 4px #AAA; box-shadow: 3px 3px 4px #AAA; } td, th { border: 1px solid #D3D3D3; padding: 5px 10px 5px 10px; } th { border-bottom: 1px solid gray; background-color: #29345C50; } .error, .warning {background-color: #f0f099;} .error{ color: #ff0000;} .warning { color: #b36b00;}</style></head><body><h1>Swiftlint Report</h1><hr /><h2>Violations</h2><table border=\"1\" style=\"vertical-align: top; height: 64px;\"><thead><tr><th style=\"width: 60pt;\"><b>Serial No.</b></th><th style=\"width: 500pt;\"><b>File</b></th><th style=\"width: 60pt;\"><b>Location</b></th><th style=\"width: 60pt;\"><b>Severity</b></th><th style=\"width: 500pt;\"><b>Message</b></th></tr></thead><tbody>__table_rows__</tbody></table><br/><h2>Summary</h2><table border=\"1\" style=\"vertical-align: top; height: 64px;\"><tbody><tr><td>Total files with violations</td><td>__number_of_files__</td></tr><tr><td>Total warnings</td><td>__number_of_warnings__</td></tr><tr><td>Total errors</td><td>__number_of_errors__</td></tr></tbody></table><hr /><p>Created with <a href=\"https://github.com/realm/SwiftLint\"><b>Swiftlint</b></a> __version__ on: __report_date__</p></body></html>"// swiftlint:disable:this line_length
return "\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td align=\"right\">\(index)</td>\n" +
"\t\t\t\t\t<td>\(location.file ?? "")</td>\n" +
"\t\t\t\t\t<td align=\"center\">\(location.line ?? 0):\(location.character ?? 0)</td>\n" +
"\t\t\t\t\t<td class=\'\(severity.lowercaseString)\'>\(severity) </td>\n" +
"\t\t\t\t\t<td>\(violation.reason)</td>\n" +
"\t\t\t\t</tr>\n"
}
}
100 changes: 98 additions & 2 deletions Tests/SwiftLintFramework/ReporterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,103 @@ class ReporterTests: XCTestCase {
formatter.dateStyle = .ShortStyle
let dateString = formatter.stringFromDate(NSDate())

let originalHTML = "<!doctype html><html><head><title>Swiftlint Report</title><style type='text/css'>table { border: 1px solid gray; border-collapse: collapse; -moz-box-shadow: 3px 3px 4px #AAA; -webkit-box-shadow: 3px 3px 4px #AAA; box-shadow: 3px 3px 4px #AAA; } td, th { border: 1px solid #D3D3D3; padding: 5px 10px 5px 10px; } th { border-bottom: 1px solid gray; background-color: #29345C50; } .error, .warning {background-color: #f0f099;} .error{ color: #ff0000;} .warning { color: #b36b00;}</style></head><body><h1>Swiftlint Report</h1><hr /><h2>Violations</h2><table border=\"1\" style=\"vertical-align: top; height: 64px;\"><thead><tr><th style=\"width: 60pt;\"><b>Serial No.</b></th><th style=\"width: 500pt;\"><b>File</b></th><th style=\"width: 60pt;\"><b>Location</b></th><th style=\"width: 60pt;\"><b>Severity</b></th><th style=\"width: 500pt;\"><b>Message</b></th></tr></thead><tbody><tr><td align=\"right\">1</td><td>filename</td><td align=\"center\">1:2</td><td class='warning'>Warning </td><td>Violation Reason.</td></tr><tr><td align=\"right\">2</td><td>filename</td><td align=\"center\">1:2</td><td class='error'>Error </td><td>Violation Reason.</td></tr></tbody></table><br/><h2>Summary</h2><table border=\"1\" style=\"vertical-align: top; height: 64px;\"><tbody><tr><td>Total files with violations</td><td>1</td></tr><tr><td>Total warnings</td><td>1</td></tr><tr><td>Total errors</td><td>1</td></tr></tbody></table><hr /><p>Created with <a href=\"https://github.com/realm/SwiftLint\"><b>Swiftlint</b></a> 0.12.0 on: \(dateString)</p></body></html>"// swiftlint:disable:this line_length
XCTAssertEqual(generatedHTML, originalHTML)
let bundle = NSBundle(identifier: "io.realm.SwiftLintFramework")!
let version = bundle.objectForInfoDictionaryKey("CFBundleShortVersionString")
let v = (version as? String ?? "0.0.0")

let expectedHTML = "<!doctype html>\n" +
"<html>\n" +
"\t<head>\n" +
"\t\t<title>Swiftlint Report</title>\n" +
"\t\t<style type='text/css'>\n" +
"\t\t\ttable {\n" +
"\t\t\t\tborder: 1px solid gray;\n" +
"\t\t\t\tborder-collapse: collapse;\n" +
"\t\t\t\t-moz-box-shadow: 3px 3px 4px #AAA;\n" +
"\t\t\t\t-webkit-box-shadow: 3px 3px 4px #AAA;\n" +
"\t\t\t\tbox-shadow: 3px 3px 4px #AAA;\n" +
"\t\t\t}\n" +
"\t\ttd, th {\n" +
"\t\t\t\tborder: 1px solid #D3D3D3;\n" +
"\t\t\t\tpadding: 5px 10px 5px 10px;\n" +
"\t\t}\n" +
"\t\tth {\n" +
"\t\t\tborder-bottom: 1px solid gray;\n" +
"\t\t\tbackground-color: #29345C50;\n" +
"\t\t}\n" +
"\t\t.error, .warning {\n" +
"\t\t\tbackground-color: #f0f099;\n" +
"\t\t} .error{ color: #ff0000;}\n" +
"\t\t.warning { color: #b36b00;\n" +
"\t\t}\n" +
"\t\t</style>\n" +
"\t</head>\n" +
"\t<body>\n" +
"\t\t<h1>Swiftlint Report</h1>\n" +
"\t\t<hr />\n" +
"\t\t<h2>Violations</h2>\n" +
"\t\t<table border=\"1\" style=\"vertical-align: top; height: 64px;\">\n" +
"\t\t\t<thead>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<th style=\"width: 60pt;\">\n" +
"\t\t\t\t\t\t<b>Serial No.</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 500pt;\">\n" +
"\t\t\t\t\t\t<b>File</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 60pt;\">\n" +
"\t\t\t\t\t\t<b>Location</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 60pt;\">\n" +
"\t\t\t\t\t\t<b>Severity</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t\t<th style=\"width: 500pt;\">\n" +
"\t\t\t\t\t\t<b>Message</b>\n" +
"\t\t\t\t\t</th>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t</thead>\n" +
"\t\t\t<tbody>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td align=\"right\">1</td>\n" +
"\t\t\t\t\t<td>filename</td>\n" +
"\t\t\t\t\t<td align=\"center\">1:2</td>\n" +
"\t\t\t\t\t<td class='warning'>Warning </td>\n" +
"\t\t\t\t\t<td>Violation Reason.</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td align=\"right\">2</td>\n" +
"\t\t\t\t\t<td>filename</td>\n" +
"\t\t\t\t\t<td align=\"center\">1:2</td>\n" +
"\t\t\t\t\t<td class='error'>Error </td>\n" +
"\t\t\t\t\t<td>Violation Reason.</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t</tbody>\n" +
"\t\t</table>\n" +
"\t\t<br/>\n" +
"\t\t<h2>Summary</h2>\n" +
"\t\t<table border=\"1\" style=\"vertical-align: top; height: 64px;\">\n" +
"\t\t\t<tbody>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td>Total files with violations</td>\n" +
"\t\t\t\t\t<td>1</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td>Total warnings</td>\n" +
"\t\t\t\t\t<td>1</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t\t<tr>\n" +
"\t\t\t\t\t<td>Total errors</td>\n" +
"\t\t\t\t\t<td>1</td>\n" +
"\t\t\t\t</tr>\n" +
"\t\t\t</tbody>\n" +
"\t\t</table>\n" +
"\t\t<hr />\n" +
"\t\t<p>Created with <a href=\"https://github.com/realm/SwiftLint\">\n" +
"\t\t\t<b>Swiftlint</b>\n" +
"\t\t</a> " + v + " on: " + dateString + "</p>\n" +
"\t</body>\n" +
"</html>"

XCTAssertEqual(generatedHTML, expectedHTML)
}
}

0 comments on commit af7404a

Please sign in to comment.