001/* 002 * Copyright (C) 2009-2011 Mathias Doenitz 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.parboiled.testing; 018 019import org.parboiled.Node; 020import org.parboiled.Rule; 021import org.parboiled.buffers.InputBuffer; 022import org.parboiled.common.Predicate; 023import org.parboiled.parserunners.RecoveringParseRunner; 024import org.parboiled.parserunners.ReportingParseRunner; 025import org.parboiled.support.ParsingResult; 026import org.parboiled.parserunners.RecoveringParseRunner; 027import org.parboiled.parserunners.ReportingParseRunner; 028import org.parboiled.support.ParseTreeUtils; 029import org.parboiled.support.ParsingResult; 030 031import java.util.ArrayList; 032import java.util.Arrays; 033import java.util.Collections; 034import java.util.List; 035 036import static org.parboiled.errors.ErrorUtils.printParseErrors; 037import static org.parboiled.support.ParseTreeUtils.printNodeTree; 038 039public abstract class ParboiledTest<V> { 040 041 public class TestResult<V> { 042 public final ParsingResult<V> result; 043 044 public TestResult(ParsingResult<V> result) { 045 this.result = result; 046 } 047 048 public TestResult<V> hasNoErrors() { 049 if (result.hasErrors()) { 050 fail("\n--- ParseErrors ---\n" + 051 printParseErrors(result) + 052 "\n--- ParseTree ---\n" + 053 ParseTreeUtils.printNodeTree(result) 054 ); 055 } 056 return this; 057 } 058 059 public TestResult<V> hasErrors(String expectedErrors) { 060 assertEquals(printParseErrors(result), expectedErrors); 061 return this; 062 } 063 064 public TestResult<V> hasParseTree(String expectedTree) { 065 assertEquals(ParseTreeUtils.printNodeTree(result), expectedTree); 066 return this; 067 } 068 069 public TestResult<V> hasParseTree(Predicate<Node<V>> nodeFilter, Predicate<Node<V>> subTreeFilter, 070 String expectedTree) { 071 assertEquals(ParseTreeUtils.printNodeTree(result, nodeFilter, subTreeFilter), expectedTree); 072 return this; 073 } 074 075 public TestResult<V> hasResult(V... expectedResults) { 076 assertEquals(toListReversed(result.valueStack), Arrays.asList(expectedResults)); 077 return this; 078 } 079 080 private <T> List<T> toListReversed(Iterable<T> iterable) { 081 List<T> list = new ArrayList<T>(); 082 for (T t : iterable) list.add(t); 083 Collections.reverse(list); 084 return list; 085 } 086 } 087 088 public TestResult<V> test(Rule rule, String input) { 089 return new TestResult<V>(new ReportingParseRunner<V>(rule).run(input)); 090 } 091 092 public TestResult<V> test(Rule rule, InputBuffer inputBuffer) { 093 return new TestResult<V>(new ReportingParseRunner<V>(rule).run(inputBuffer)); 094 } 095 096 public TestResult<V> testWithRecovery(Rule rule, String input) { 097 return new TestResult<V>(new RecoveringParseRunner<V>(rule).run(input)); 098 } 099 100 public TestResult<V> testWithRecovery(Rule rule, InputBuffer inputBuffer) { 101 return new TestResult<V>(new RecoveringParseRunner<V>(rule).run(inputBuffer)); 102 } 103 104 protected abstract void fail(String message); 105 106 protected abstract void assertEquals(Object actual, Object expected); 107}