mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Add JSON formatter
This commit is contained in:
parent
9708b94587
commit
4546b90b54
3 changed files with 212 additions and 0 deletions
78
spec/ameba/formatter/json_formatter_spec.cr
Normal file
78
spec/ameba/formatter/json_formatter_spec.cr
Normal file
|
@ -0,0 +1,78 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
def get_result(sources = [Source.new ""])
|
||||
file = IO::Memory.new
|
||||
formatter = Formatter::JSONFormatter.new file
|
||||
|
||||
formatter.started sources
|
||||
sources.each { |source| formatter.source_finished source }
|
||||
formatter.finished sources
|
||||
|
||||
JSON.parse file.to_s
|
||||
end
|
||||
|
||||
describe Formatter::JSONFormatter do
|
||||
context "metadata" do
|
||||
it "shows ameba version" do
|
||||
get_result["metadata"]["ameba_version"].should eq Ameba::VERSION
|
||||
end
|
||||
|
||||
it "shows crystal version" do
|
||||
get_result["metadata"]["crystal_version"].should eq Crystal::VERSION
|
||||
end
|
||||
end
|
||||
|
||||
context "sources" do
|
||||
it "shows path to the source" do
|
||||
result = get_result [Source.new "", "source.cr"]
|
||||
result["sources"].first["path"].should eq "source.cr"
|
||||
end
|
||||
|
||||
it "shows rule name" do
|
||||
s = Source.new ""
|
||||
s.error DummyRule.new, 1, 2, "message1"
|
||||
|
||||
result = get_result [s]
|
||||
result["sources"].first["errors"].first["rule_name"].should eq DummyRule.name
|
||||
end
|
||||
|
||||
it "shows a message" do
|
||||
s = Source.new ""
|
||||
s.error DummyRule.new, 1, 2, "message"
|
||||
|
||||
result = get_result [s]
|
||||
result["sources"].first["errors"].first["message"].should eq "message"
|
||||
end
|
||||
|
||||
it "shows error location" do
|
||||
s = Source.new ""
|
||||
s.error DummyRule.new, 1, 2, "message"
|
||||
|
||||
result = get_result [s]
|
||||
location = result["sources"].first["errors"].first["location"]
|
||||
location["line"].should eq 1
|
||||
location["column"].should eq 2
|
||||
end
|
||||
end
|
||||
|
||||
context "summary" do
|
||||
it "shows a target sources count" do
|
||||
result = get_result [Source.new(""), Source.new("")]
|
||||
result["summary"]["target_sources_count"].should eq 2
|
||||
end
|
||||
|
||||
it "shows errors count" do
|
||||
s1 = Source.new ""
|
||||
s1.error DummyRule.new, 1, 2, "message1"
|
||||
s1.error DummyRule.new, 1, 2, "message2"
|
||||
|
||||
s2 = Source.new ""
|
||||
s2.error DummyRule.new, 1, 2, "message3"
|
||||
|
||||
result = get_result [s1, s2]
|
||||
result["summary"]["errors_count"].should eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -18,6 +18,7 @@ class Ameba::Config
|
|||
flycheck: Formatter::FlycheckFormatter,
|
||||
silent: Formatter::BaseFormatter,
|
||||
disabled: Formatter::DisabledFormatter,
|
||||
json: Formatter::JSONFormatter,
|
||||
}
|
||||
|
||||
PATH = ".ameba.yml"
|
||||
|
|
133
src/ameba/formatter/json_formatter.cr
Normal file
133
src/ameba/formatter/json_formatter.cr
Normal file
|
@ -0,0 +1,133 @@
|
|||
require "json"
|
||||
|
||||
module Ameba::Formatter
|
||||
# A formatter that produces the result in a json format.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# ```
|
||||
# {
|
||||
# "metadata": {
|
||||
# "ameba_version": "x.x.x",
|
||||
# "crystal_version": "x.x.x",
|
||||
# },
|
||||
# "sources": [
|
||||
# {
|
||||
# "errors": [
|
||||
# {
|
||||
# "location": {
|
||||
# "column": 7,
|
||||
# "line": 17,
|
||||
# },
|
||||
# "message": "Useless assignment to variable `a`",
|
||||
# "rule_name": "UselessAssign",
|
||||
# },
|
||||
# {
|
||||
# "location": {
|
||||
# "column": 7,
|
||||
# "line": 18,
|
||||
# },
|
||||
# "message": "Useless assignment to variable `a`",
|
||||
# "rule_name": "UselessAssign",
|
||||
# },
|
||||
# {
|
||||
# "location": {
|
||||
# "column": 7,
|
||||
# "line": 19,
|
||||
# },
|
||||
# "message": "Useless assignment to variable `a`",
|
||||
# "rule_name": "UselessAssign",
|
||||
# },
|
||||
# ],
|
||||
# "path": "src/ameba/formatter/json_formatter.cr",
|
||||
# },
|
||||
# ],
|
||||
# "summary": {
|
||||
# "errors_count": 3,
|
||||
# "target_sources_count": 1,
|
||||
# },
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
class JSONFormatter < BaseFormatter
|
||||
def initialize(@output = STDOUT)
|
||||
@result = AsJSON::Result.new
|
||||
end
|
||||
|
||||
def started(sources)
|
||||
@result.summary.target_sources_count = sources.size
|
||||
end
|
||||
|
||||
def source_finished(source : Source)
|
||||
json_source = AsJSON::Source.new source.path
|
||||
|
||||
source.errors.each do |e|
|
||||
next if e.disabled?
|
||||
json_source.errors << AsJSON::Error.new(e.rule.name, e.location, e.message)
|
||||
@result.summary.errors_count += 1
|
||||
end
|
||||
|
||||
@result.sources << json_source
|
||||
end
|
||||
|
||||
def finished(sources)
|
||||
@result.to_json @output
|
||||
end
|
||||
end
|
||||
|
||||
private module AsJSON
|
||||
record Result,
|
||||
sources = [] of Source,
|
||||
metadata = Metadata.new,
|
||||
summary = Summary.new do
|
||||
def to_json(json)
|
||||
{sources: sources, metadata: metadata, summary: summary}.to_json(json)
|
||||
end
|
||||
end
|
||||
|
||||
record Source,
|
||||
path : String,
|
||||
errors = [] of Error do
|
||||
def to_json(json)
|
||||
{path: path, errors: errors}.to_json(json)
|
||||
end
|
||||
end
|
||||
|
||||
record Error,
|
||||
rule_name : String,
|
||||
location : Crystal::Location?,
|
||||
message : String do
|
||||
def to_json(json)
|
||||
json.object do
|
||||
json.field :rule_name, rule_name
|
||||
json.field :message, message
|
||||
json.field :location,
|
||||
{line: location.try &.line_number, column: location.try &.column_number}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
record Metadata,
|
||||
ameba_version : String = Ameba::VERSION,
|
||||
crystal_version : String = Crystal::VERSION do
|
||||
def to_json(json)
|
||||
json.object do
|
||||
json.field :ameba_version, ameba_version
|
||||
json.field :crystal_version, crystal_version
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Summary
|
||||
property target_sources_count = 0
|
||||
property errors_count = 0
|
||||
|
||||
def to_json(json)
|
||||
json.object do
|
||||
json.field :target_sources_count, target_sources_count
|
||||
json.field :errors_count, errors_count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue