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…
	
	Add table
		Add a link
		
	
		Reference in a new issue