com.legstar.pli2cob.AbstractTester.java Source code

Java tutorial

Introduction

Here is the source code for com.legstar.pli2cob.AbstractTester.java

Source

/*******************************************************************************
 * Copyright (c) 2009 LegSem.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     LegSem - initial API and implementation
 ******************************************************************************/
package com.legstar.pli2cob;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;

import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.antlr.runtime.tree.DOTTreeGenerator;
import org.antlr.runtime.tree.Tree;
import org.antlr.runtime.tree.TreeNodeStream;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.legstar.antlr.ANTLRNoCaseReaderStream;
import com.legstar.pli2cob.PLIStructureParser.pl1code_return;
import com.legstar.pli2cob.model.PLIDataItem;

import junit.framework.TestCase;

/**
 * Common test helper code.
 *
 */
public abstract class AbstractTester extends TestCase {

    /** Line separator (OS specific).*/
    public static final String LS = System.getProperty("line.separator");

    /** Logger. */
    private final Log _log = LogFactory.getLog(getClass());

    /**
     * Apply the lexer to produce a token stream from source.
     * @param source the source code
     * @return an antlr token stream
     */
    public CommonTokenStream lexify(final String source) {
        try {
            PLIStructureLexer lex = new PLIStructureLexerImpl(
                    new ANTLRNoCaseReaderStream(new StringReader(source)));
            CommonTokenStream tokens = new CommonTokenStream(lex);
            assertEquals(0, lex.getNumberOfSyntaxErrors());
            assertTrue(tokens != null);
            return tokens;
        } catch (IOException e) {
            _log.error("test failed", e);
            fail(e.toString());
        }
        return null;
    }

    /**
     * Apply Lexer + Parser to produce an abstract syntax tree from source. 
     * @param source the source code
     * @return an antlr abstract syntax tree
     */
    public CommonTree parse(final String source) {
        try {
            CommonTokenStream tokens = lexify(source);
            PLIStructureParser parser = new PLIStructureParserImpl(tokens);
            pl1code_return parserResult = parser.pl1code();
            assertEquals(0, parser.getNumberOfSyntaxErrors());
            assertTrue(parserResult != null);
            return (CommonTree) parserResult.getTree();
        } catch (RecognitionException e) {
            e.printStackTrace();
            fail(e.toString());
        }
        return null;
    }

    /**
     * A generic test helper that takes a source fragment and checks the result.
     * @param source the source fragment
     * @param expected the expected sub graph
     */
    public void parseAndCheck(final String source, final String expected) {
        CommonTree ast = parse(source);
        if (_log.isDebugEnabled()) {
            _log.debug(getGraph(ast).toString());
        }
        assertEquals(expected, (ast == null) ? "" : ast.toStringTree());
    }

    /**
     * Apply Lexer + Parser + Enhancer to produce an abstract syntax tree from source. 
     * @param source the source code
     * @return an antlr abstract syntax tree where nodes are normalized
     */
    public CommonTree parseAndEnhance(final String source) {
        try {
            CommonTree ast = parse(source);
            if (_log.isDebugEnabled()) {
                _log.debug(ast.toStringTree());
            }
            TreeNodeStream nodes = new CommonTreeNodeStream(ast);
            PLIStructureEnhancer enhancer = new PLIStructureEnhancer(nodes);
            return enhancer.pl1code().tree;
        } catch (RecognitionException e) {
            e.printStackTrace();
            fail(e.toString());
        }
        return null;
    }

    /**
     * Starting from a PL/I source fragment translates to COBOL.
     * @param source PL/I source fragment.
     * @return a COBOL fragment
     * @throws Exception if emit fails
     */
    private String emit(final String source) throws Exception {
        CommonTree ast = parse(source);
        if (_log.isDebugEnabled()) {
            _log.debug(ast.toStringTree());
        }
        TreeNodeStream nodes = new CommonTreeNodeStream(ast);
        PLIStructureCobolEmitter emitter = new PLIStructureCobolEmitter(nodes);
        StringTemplateGroup stgGroup = new StringTemplateGroup(
                new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/pli2cob.stg"))));
        emitter.setTemplateLib(stgGroup);
        PLIStructureCobolEmitter.pl1code_return r = emitter.pl1code();
        StringTemplate output = (StringTemplate) r.getTemplate();
        return output.toString();
    }

    /**
     * Translate PL/I fragment to COBOL and test it against an expected result.
     * <p/>
     * For convenience we trim the generated COBOL comment header so that it does
     * not clutter the expected results.
     * <p/>
     * We also trim the last newline sequence if any.
     * @param source PL/I source fragment
     * @param expected expected COBOL fragment
     * @throws Exception if test fails
     */
    public void emitAndCheck(final String source, final String expected) throws Exception {
        String result = emit(source);
        if (result == null) {
            if (expected == null) {
                return;
            }
            fail();
        }
        assertEquals(expected, trimCobolComment(result));
    }

    /**
     * A helper to perform a PLI to COBOL conversion.
     * @param source the PLI source fragment
     * @param expected the expected COBOL result
     * @param syncpad whether to generate padding for PLI alignments
     * @param synchang whether to generate initial hang for PL/I alignment.
     */
    public void translateAndCheck(final String source, final String expected, final boolean syncpad,
            final boolean synchang) {
        try {
            PLIStructureToCobol pli2cob = new PLIStructureToCobol();
            pli2cob.getContext().setAddPAd(syncpad);
            pli2cob.getContext().setAddHang(synchang);
            assertEquals(expected, trimCobolComment(pli2cob.translate(source)));
        } catch (Exception e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }

    /**
     * Generated source will start with a comment header that we remove
     * here to prevent all expected results to have to specify this
     * comment.
     * <p/>
     * Also trims trailing new line for convenience
     * @param source the source code to trim
     * @return source without comment header (if any)
     */
    public String trimCobolComment(final String source) {
        String result = source;
        int idx = result
                .indexOf("" + "      *" + LS + "      * Generated by legstar-pli2cob" + LS + "      *" + LS);
        if (idx > -1) {
            result = result.substring(
                    ("      *" + LS + "      * Generated by legstar-pli2cob" + LS + "      *" + LS).length());
        }
        int lnli = result.lastIndexOf(LS);
        if (lnli > -1) {
            result = result.substring(0, result.length() - LS.length());
        }
        return result;
    }

    /**
     * @param source a single declare source fragment
     * @return the corresponding data item
     */
    public PLIDataItem getPLIDataItem(final String source) {
        CommonTree ast = parseAndEnhance(source);
        return new PLIDataItem(ast, null);
    }

    /**
     * Produce a graphviz source for an abstract syntax tree.
     * @param ast the abstract syntax tree
     * @return a graphviz source
     */
    public String getGraph(final Tree ast) {
        DOTTreeGenerator gen = new DOTTreeGenerator();
        StringTemplate st = gen.toDOT(ast);
        return st.toString();
    }

    /**
     * Fetch the entire contents of a text file, and return it in a String.
     * @param file some file
     * @return the file content
     */
    public String getFileContent(final File file) {
        StringBuilder contents = new StringBuilder();
        try {
            BufferedReader input = new BufferedReader(new FileReader(file));
            try {
                String line = null;
                while ((line = input.readLine()) != null) {
                    contents.append(line);
                    contents.append(LS);
                }
            } finally {
                input.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        return contents.toString();
    }

}