require_relative 'spec_helper'
require 'stringio'

describe Scanner do
  before do
    @scanner = Scanner.new(InlineCommentSpaceWarning::OPTION_KEY => 2)

    @fix_scanner_stdout = StringIO.new
    @fix_scanner = Scanner.new(fix: true, output_file: @fix_scanner_stdout)
  end

  describe '#scan' do
    it 'takes an input and gathers warnings about it' do
      warnings = @scanner.scan('1 + 2 ', '(stdin)')
      warnings.size.should == 1
      warnings[0].should be_a(ExtraWhitespaceWarning)
    end

    it "ignores warnings specified in the line's comments by class name" do
      warnings = @scanner.scan('1 +2  # laser: ignore OperatorSpacing')
      warnings.size.should == 0
    end

    it "ignores warnings specified in the line's comments by short name" do
      warnings = @scanner.scan("1 +2  # laser: ignore #{OperatorSpacing.short_name}")
      warnings.size.should == 0
    end

    it "ignores multiple warnings that are marked in the line's comments" do
      warnings = @scanner.scan(
          '1 +2; 3 + 4  # laser: ignore OperatorSpacing SemicolonWarning')
      warnings.size.should == 0
    end

    it "ignores multiple warnings in the line's comments as short name" do
      warnings = @scanner.scan(
          "1 +2; 3 + 4  # laser: ignore #{OperatorSpacing.short_name} #{SemicolonWarning.short_name}")
      warnings.size.should == 0
    end

    it 'fixes the input and writes it to :output_file' do
      warnings = @fix_scanner.scan('1 + 2 ', '(stdin)')
      warnings.size.should == 1
      warnings[0].should be_a(ExtraWhitespaceWarning)
      @fix_scanner_stdout.string.should == "1 + 2"
    end

    it 'fixes multiple errors on one line' do
      warnings = @fix_scanner.scan('1 +2 ', '(stdin)')
      warnings.size.should == 2
      @fix_scanner_stdout.string.should == "1 + 2"
    end

    it 'fixes multiline inputs' do
      warnings = @fix_scanner.scan("def plus(a, b)\n  a + b \nend", '(stdin)')
      warnings.size.should == 1
      warnings[0].should be_a(ExtraWhitespaceWarning)
      @fix_scanner_stdout.string.should == "def plus(a, b)\n  a + b\nend"
    end

    it 'fixes multiline mis-indented inputs' do
      warnings = @fix_scanner.scan("def plus(a, b)\n  a + b\n end", '(stdin)')
      warnings.size.should == 1
      warnings[0].should be_a(MisalignedUnindentationWarning)
      @fix_scanner_stdout.string.should == "def plus(a, b)\n  a + b\nend"
    end

    it 'fixes class definitions' do
      warnings = @fix_scanner.scan("class Hello\n  1+2\nend", '(stdin)')
      warnings.size.should == 1
      warnings[0].should be_a(OperatorSpacing)
      @fix_scanner_stdout.string.should == "class Hello\n  1 + 2\nend"
    end
  end
end
