Package com.eclipsesource.jshint

Source Code of com.eclipsesource.jshint.JSHint_Test$TestHandler

/*******************************************************************************
* Copyright (c) 2012, 2013 EclipseSource.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Ralf Sternberg - initial implementation and API
******************************************************************************/
package com.eclipsesource.jshint;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.mozilla.javascript.EcmaError;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

import com.eclipsesource.json.JsonObject;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;


public class JSHint_Test {

  private List<Problem> problems;
  private TestHandler handler;
  private JSHint jsHint;

  @Before
  public void setUp() throws IOException {
    problems = new ArrayList<Problem>();
    handler = new TestHandler( problems );
    jsHint = new JSHint();
    jsHint.load();
  }

  @Test
  public void getDefaultVersion() {
    String version = JSHint.getDefaultLibraryVersion();

    assertTrue( version.matches( "\\d+\\.\\d+\\.\\d+" ) );
  }

  @Test( expected = NullPointerException.class )
  public void configureWithNull() {
    jsHint.configure( null );
  }

  @Test
  public void configureBeforeLoad() throws Exception {
    JsonObject configuration = new JsonObject().add( "undef", true );

    JSHint jsHint = new JSHint();
    jsHint.configure( configuration );
    jsHint.load();
    jsHint.check( "x = 23;", handler );

    assertEquals( "'x' is not defined", problems.get( 0 ).getMessage() );
  }

  @Test
    public void loadBeforeConfigure() throws Exception {
    JsonObject configuration = new JsonObject().add( "undef", true );

    JSHint jsHint = new JSHint();
    jsHint.load();
    jsHint.configure( configuration );
    jsHint.check( "x = 23;", handler );

    assertEquals( "'x' is not defined", problems.get( 0 ).getMessage() );
  }

  @Test( expected = IllegalStateException.class )
  public void checkWithoutLoad() {
    JSHint jsHint = new JSHint();
    jsHint.check( "code", handler );
  }

  @Test( expected = NullPointerException.class )
  public void checkWithNullCode() {
    jsHint.check( (String)null, handler );
  }

  @Test( expected = NullPointerException.class )
  public void checkWithNullText() {
    jsHint.check( (Text)null, handler );
  }

  @Test
  public void checkWithNullHandler() {
    assertTrue( jsHint.check( "var a = 23;", null ) );
    assertFalse( jsHint.check( "HMPF!", null ) );
  }

  @Test( expected = NullPointerException.class )
  public void loadCustomWithNullParameter() throws Exception {
    JSHint jsHint = new JSHint();
    jsHint.load( null );
  }

  @Test
  public void loadCustomWithEmptyFile() throws Exception {
    JSHint jsHint = new JSHint();
    try {
      jsHint.load( new ByteArrayInputStream( "".getBytes() ) );
      fail();
    } catch( IllegalArgumentException exception ) {
      assertEquals( "Global JSHINT function missing in input", exception.getMessage() );
    }
  }

  @Test
  public void loadCustomWithWrongJsFile() throws Exception {
    JSHint jsHint = new JSHint();
    try {
      jsHint.load( new ByteArrayInputStream( "var a = 23;".getBytes() ) );
      fail();
    } catch( IllegalArgumentException exception ) {
      assertEquals( "Global JSHINT function missing in input", exception.getMessage() );
    }
  }

  @Test
  public void loadCustomWithFakeJsHintFile() throws Exception {
    JSHint jsHint = new JSHint();
    try {
      jsHint.load( new ByteArrayInputStream( "JSHINT = {};".getBytes() ) );
      fail();
    } catch( IllegalArgumentException exception ) {
      assertEquals( "Global JSHINT is not a function", exception.getMessage() );
    }
  }

  @Test
  public void loadCustomWithEcmaException() throws Exception {
    JSHint jsHint = new JSHint();
    try {
      jsHint.load( new ByteArrayInputStream( "JSHINT = foo;".getBytes() ) );
      fail();
    } catch( IllegalArgumentException exception ) {
      assertEquals( "Could not evaluate JavaScript input", exception.getMessage() );
    }
  }

  @Test
  public void loadCustomWithGarbage() throws Exception {
    JSHint jsHint = new JSHint();
    try {
      jsHint.load( new ByteArrayInputStream( "cheese! :D".getBytes() ) );
      fail();
    } catch( IllegalArgumentException exception ) {
      assertEquals( "Could not evaluate JavaScript input", exception.getMessage() );
    }
  }

  @Test
  public void loadCustom() throws Exception {
    JSHint jsHint = new JSHint();
    ClassLoader classLoader = getClass().getClassLoader();
    InputStream stream = classLoader.getResourceAsStream( "com/jshint/jshint-r03.js" );
    try {
      jsHint.load( stream );
    } finally {
      stream.close();
    }

    jsHint.check( "cheese! :D", handler );

    assertFalse( problems.isEmpty() );
  }

  @Test
  public void checkWithEmptyCode() {
    boolean result = jsHint.check( "", handler );

    assertTrue( result );
    assertTrue( problems.isEmpty() );
  }

  @Test
  public void checkWithOnlyWhitespace() {
    boolean result = jsHint.check( " ", handler );

    assertTrue( result );
    assertTrue( problems.isEmpty() );
  }

  @Test
  public void checkWithValidCode() {
    boolean result = jsHint.check( "var foo = 23;", handler );

    assertTrue( result );
    assertTrue( problems.isEmpty() );
  }

  @Test
  public void checkWithSyntaxError() {
    boolean result = jsHint.check( "cheese!", handler );

    assertFalse( result );
    assertTrue( problems.get( 0 ).isError() );
  }

  @Test
  public void checkWithWarning() {
    boolean result = jsHint.check( "x = 23", handler ); // missing semicolon

    assertFalse( result );
    assertFalse( problems.get( 0 ).isError() );
  }

  @Test
  public void checkWithJavaScriptException() throws Exception {
    JSHint jsHint = new JSHint();
    jsHint.load( new ByteArrayInputStream( "JSHINT = function() { throw 'ERROR'; };".getBytes() ) );

    try {
      jsHint.check( "var a = 1;", handler );
      fail();
    } catch( RuntimeException exception ) {

      String expected = "JavaScript exception thrown by JSHint: ERROR";
      assertThat( exception.getMessage(), startsWith( expected ) );
      assertSame( JavaScriptException.class, exception.getCause().getClass() );
    }
  }

  @Test
  public void checkWithRhinoException() throws Exception {
    JSHint jsHint = new JSHint();
    jsHint.load( new ByteArrayInputStream( "JSHINT = function() { throw x[ 0 ]; };".getBytes() ) );

    try {
      jsHint.check( "var a = 1;", handler );
      fail();
    } catch( RuntimeException exception ) {

      String expected = "JavaScript exception caused by JSHint: ReferenceError";
      assertThat( exception.getMessage(), startsWith( expected ) );
      assertSame( EcmaError.class, exception.getCause().getClass() );
    }
  }

  public void createdProblemsContainErrorCode() {
    jsHint.check( "x = 1", handler );

    problems.get( 0 ).getCode().matches( "^W\\d+" );
  }

  @Test
  public void noErrorsWithoutConfig() {
    // undefined variable is only reported with 'undef' in config
    jsHint.check( "var f = function () { v = {}; };", handler );

    assertTrue( problems.isEmpty() );
  }

  @Test
  public void noErrorsWithEmptyConfig() {
    // undefined variable is only reported with 'undef' in config
    jsHint.configure( new JsonObject() );

    jsHint.check( "var f = function () { v = {}; };", handler );

    assertTrue( problems.isEmpty() );
  }

  @Test
  public void errorWithUndefInConfig() {
    jsHint.configure( new JsonObject().add( "undef", true ) );

    jsHint.check( "var f = function () { v = {}; };", handler );

    assertThat( problems.get( 0 ).getMessage(), containsString( "'v' is not defined" ) );
  }

  @Test
  public void errorAfterTabHasSamePositionAsAfterSpace() {
    jsHint.configure( new JsonObject().add( "undef", true ) );
    jsHint.check( "var x = 1, # y = 2;", handler );
    Problem problemWithSpace = problems.get( 0 );
    problems.clear();

    jsHint.check( "var x = 1,\t# y = 2;", handler );

    Problem problemWithTab = problems.get( 0 );
    assertEquals( problemWithSpace.getCharacter(), problemWithTab.getCharacter() );
  }

  @Test
  public void errorAtEndDoesNotThrowException() {
    jsHint.configure( new JsonObject().add( "undef", true ) );

    // Must not throw SIOOBE
    // See https://github.com/eclipsesource/jshint-eclipse/issues/34
    jsHint.check( "var x = 1;\t#", handler );
  }

  @Test
  public void checkSameInputTwice() {
    jsHint.configure( new JsonObject().add( "undef", true ) );
    LoggingHandler handler1 = new LoggingHandler();
    LoggingHandler handler2 = new LoggingHandler();

    jsHint.check( "var x = 1;\t#", handler1 );
    jsHint.check( "var x = 1;\t#", handler2 );

    assertTrue( handler1.toString().length() > 0 );
    assertEquals( handler1.toString(), handler2.toString() );
  }

  @Test
  public void checkMultipleFiles() {
    // see https://github.com/jshint/jshint/issues/931
    jsHint.configure( new JsonObject().add( "undef", true ) );

    jsHint.check( "var x = 1;\t#", handler );
    jsHint.check( "var x = 1;\t#", handler );
    jsHint.check( "var x = 1;\t#", handler );
    jsHint.check( "var x = 1;\t#", handler );
    jsHint.check( "var x = 1;\t#", handler );
  }

  @Test
  public void createProblem() {
    Text text = new Text( "line1\nline2\n" );
    ScriptableObject error = mockError( "foo", 1, 3, "T001" );

    Problem problem = jsHint.createProblem( error, text );

    assertEquals( "foo", problem.getMessage() );
    assertEquals( 1, problem.getLine() );
    assertEquals( 2, problem.getCharacter() );
    assertEquals( "T001", problem.getCode() );
  }

  @Test
  public void createProblem_cutsOffTrailingPeriodFromMessage() {
    Text text = new Text( "line1\nline2\n" );
    ScriptableObject error = mockError( "Foo.", 1, 3, "T001" );

    Problem problem = jsHint.createProblem( error, text );

    assertEquals( "Foo", problem.getMessage() );
  }

  @Test
  public void createProblem_mapsVisualToRealIndex() {
    Text text = new Text( "\tline1\n" );
    ScriptableObject error = mockError( "foo", 1, 6, "T001" );

    Problem problem = jsHint.createProblem( error, text );

    assertEquals( 1, problem.getLine() );
    assertEquals( 2, problem.getCharacter() );
  }

  @Test
  public void createProblem_toleratesIllegalLine() {
    // Protect against the case that jshint reports illegal lines
    // See https://github.com/eclipsesource/jshint-eclipse/issues/27
    //     https://github.com/eclipsesource/jshint-eclipse/issues/60
    Text text = new Text( "line1\nline2\n" );
    ScriptableObject error = mockError( "Foo.", 4, 7, "T001" );

    Problem problem = jsHint.createProblem( error, text );

    assertEquals( -1, problem.getLine() );
    assertEquals( -1, problem.getCharacter() );
  }

  /*
   * index:  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11|
   * char:   | a | » | b | » | c |
   * visual:     | a | »             | b | »             | c |
   */
  @Test
  public void visualToCharIndex() {
    Text text = new Text( "a\tb\tc" );

    assertEquals( 0, jsHint.visualToCharIndex( text, 1, 1 ) );
    assertEquals( 1, jsHint.visualToCharIndex( text, 1, 2 ) );
    assertEquals( 2, jsHint.visualToCharIndex( text, 1, 6 ) );
    assertEquals( 3, jsHint.visualToCharIndex( text, 1, 7 ) );
    assertEquals( 4, jsHint.visualToCharIndex( text, 1, 11 ) );
  }

  public void visualToCharIndex_withoutTabs() {
    Text text = new Text( "a b c" );

    assertEquals( 0, jsHint.visualToCharIndex( text, 1, 1 ) );
    assertEquals( 1, jsHint.visualToCharIndex( text, 1, 2 ) );
    assertEquals( 2, jsHint.visualToCharIndex( text, 1, 3 ) );
    assertEquals( 3, jsHint.visualToCharIndex( text, 1, 4 ) );
    assertEquals( 4, jsHint.visualToCharIndex( text, 1, 5 ) );
  }

  private static ScriptableObject mockError( String message, int line, int character, String code )
  {
    ScriptableObject error = mock( ScriptableObject.class );
    when( error.get( eq( "reason" ), any( Scriptable.class ) ) ).thenReturn( message );
    when( error.get( eq( "line" ), any( Scriptable.class ) ) ).thenReturn( Integer.valueOf( line ) );
    when( error.get( eq( "character" ), any( Scriptable.class ) ) ).thenReturn( Integer.valueOf( character ) );
    when( error.get( eq( "code" ), any( Scriptable.class ) ) ).thenReturn( code );
    return error;
  }

  private static class LoggingHandler implements ProblemHandler {

    StringBuilder log = new StringBuilder();

    public void handleProblem( Problem problem ) {
      log.append( problem.getLine() );
      log.append( ':' );
      log.append( problem.getCharacter() );
      log.append( ':' );
      log.append( problem.getMessage() );
      log.append( '\n' );
    }

    @Override
    public String toString() {
      return log.toString();
    }

  }

  private static class TestHandler implements ProblemHandler {

    private final List<Problem> problems;

    public TestHandler( List<Problem> problems ) {
      this.problems = problems;
    }

    public void handleProblem( Problem problem ) {
      problems.add( problem );
    }

  }

}
TOP

Related Classes of com.eclipsesource.jshint.JSHint_Test$TestHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.