package tool.model.grammar;
import static org.junit.Assert.fail;
import java.io.IOException;
import junit.framework.Assert;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.junit.Test;
import tool.model.grammar.ForteParser.sql_select_return;
import tool.model.grammar.ForteParser.sql_statement_return;
import tool.model.grammar.ForteParser.statement_return;
public class StatementTest {
private static final boolean PRINT_TREE = false;
private void failOnSyntaxError(String string, ForteParser parser, ForteAST ast){
int errors = 0;
int treeErrors = 0;
errors = parser.getNumberOfSyntaxErrors();
if (ast != null)
treeErrors = ast.getNumberOfSyntaxErrors();
System.out.println(string + " errors: " + errors + " tree errors: " + treeErrors);
if (errors + treeErrors> 0){
fail("Syntax errors: " + errors);
}
}
public int testStatement(String name, String source) throws IOException, RecognitionException{
int errors = 0;
ForteAST walker = null;
ForteParser parser = null;
try {
System.out.println("===== Statement: " + name + " =====");
CharStream stream =
new NoCaseStringStream(source);
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokens = new CommonTokenStream(lexer);
parser = new ForteParser(tokens);
parser.setTokenStream(tokens);
statement_return result = parser.statement();
CommonTree tree = (CommonTree) result.getTree();
errors = parser.getNumberOfSyntaxErrors();
if (errors == 0){
if (PRINT_TREE)
System.out.println("Tree==>"+tree.toStringTree());
CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
nodes.setTokenStream(tokens);
walker = new ForteAST(nodes);
walker.statement();
}
} finally {
failOnSyntaxError(name, parser, walker);
}
return errors;
}
@Test
public void localVariableSimple() throws IOException, RecognitionException{
testStatement("Simple local variable with init", "a : integer = 2;");
}
@Test
public void forEach() throws IOException, RecognitionException{
testStatement("For Each",
" for p in self.PaintingData do\n" +
" if p.Name = deletedName then\n" +
" -- This is the one. Delete it.\n" +
" self.PaintingData.DeleteRow(p);\n" +
" exit;\n" +
" end if;\n" +
" end for;\n" +
"");
}
@Test
public void forCountControlled() throws IOException, RecognitionException{
testStatement("For count controlled",
"for i in 1 to self.PaintingsUnderBid.Items do\n" +
" trc.Put(' ----BID NUMBER ');\n" +
" trc.Put(i);\n" +
" trc.PutLine('-----------------------------------');\n" +
" self.PaintingsUnderBid[i].WriteToLog();\n" +
"end for ;\n" +
"");
}
@Test
public void sql_do() throws RecognitionException{
CharStream stream =
new NoCaseStringStream("sql select * from PaintingTab\n" +
" where Painter = :painter.name\n" +
" on session self.MGRSession;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
sql_select_return sql = parser.sql_select();
CommonTree tree = (CommonTree) sql.getTree();
System.out.println("SQL:" + tree.toString());
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("sql_do " + errors + " errors");
}
}
@Test
public void forSQL() throws IOException, RecognitionException{
testStatement("For SQL",
"for (ptg : Painting) in " +
"sql select * from PaintingTab\n" +
" where Painter = :painter.name\n" +
" on session self.MGRSession do\n" +
" painter.ListOfPaintings.AppendRow(ptg);\n" +
"end for;"
);
}
@Test
public void eventLoop() throws IOException, RecognitionException{
// try {
// CharStream stream =
// new NoCaseStringStream("event loop\n" +
testStatement("Event Loop:", "event loop\n" +
" when task.Shutdown do\n" +
" if self.IsAuctioneer then\n" +
" -- Give up Auctioneer status. \n" +
" AuctionService.RelinquishAuctioneerStatus();\n" +
" end if;\n" +
" exit;\n" +
"\n" +
" --\n" +
" -- Events that might come in from the AuctionMgr, \n" +
" -- regarding updating of the painting list.\n" +
" --\n" +
" when AuctionService.PaintingDeleted \n" +
" (deletedName=paintingName) do\n" +
" --\n" +
" -- A row from the array is to be deleted. Find it \n" +
" -- and remove. If it is being displayed, the \n" +
" -- corresponding ViewPainting window will get the \n" +
" -- event as well, and close down.\n" +
" for p in self.PaintingData do\n" +
" if p.Name = deletedName then\n" +
" -- This is the one. Delete it.\n" +
" self.PaintingData.DeleteRow(p);\n" +
" exit;\n" +
" end if;\n" +
" end;\n" +
"end event;");
// ForteLexer lexer = new ForteLexer(stream);
// TokenStream tokenStream = new CommonTokenStream(lexer);
// ForteParser parser = new ForteParser(tokenStream);
// CommonTree tree = (CommonTree) parser.eventLoopStatement().getTree();
// System.out.println(tree.toStringTree());
// int errors = parser.getNumberOfSyntaxErrors();
// if (errors > 0){
// Assert.fail("eventLoop " + errors + " errors");
// }
// } catch (RecognitionException e) {
// Assert.fail(e.getMessage());
// }
}
@Test
public void eventWhen(){
try {
CharStream stream =
new NoCaseStringStream(
" when task.Shutdown do\n" +
" if self.IsAuctioneer then\n" +
" -- Give up Auctioneer status. \n" +
" AuctionService.RelinquishAuctioneerStatus();\n" +
" end if;\n" +
" exit;\n" +
"\n" +
" --\n" +
" -- Events that might come in from the AuctionMgr, \n" +
" -- regarding updating of the painting list.\n" +
" --\n" +
" when AuctionService.PaintingDeleted \n" +
" (deletedName=paintingName) do\n" +
" --\n" +
" -- A row from the array is to be deleted. Find it \n" +
" -- and remove. If it is being displayed, the \n" +
" -- corresponding ViewPainting window will get the \n" +
" -- event as well, and close down.\n" +
" for p in self.PaintingData do\n" +
" if p.Name = deletedName then\n" +
" -- This is the one. Delete it.\n" +
" self.PaintingData.DeleteRow(p);\n" +
" exit;\n" +
" end if;\n" +
" end for;\n"
);
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
CommonTree tree = (CommonTree) parser.whenss().getTree();
// System.out.println(tree.toStringTree());
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("eventWhen " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void assignmentStatement_1(){
try {
CharStream stream =
new NoCaseStringStream("self.legs(34).value = 7;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("assignmentStatement completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void assignmentStatement_2(){
try {
CharStream stream =
new NoCaseStringStream("self.legs[34].value = 7;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("assignmentStatement_2 completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void assignmentStatement_3(){
try {
CharStream stream =
new NoCaseStringStream("self.legs[34] = 7;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("assignmentStatement completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void simpleMethodInvocationStatement(){
try {
CharStream stream =
new NoCaseStringStream("__PutProperty(17,OLE.VariantI2(Value='Action'));");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("simpleMethodInvocationStatement completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void ifStatement_1(){
try {
CharStream stream =
new NoCaseStringStream("if a then\n" +
"x = y;" +
"end if;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("ifStatement_1 completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void ifStatement_2(){
try {
CharStream stream =
new NoCaseStringStream("if a = b then\n" +
"x = y;" +
"end if;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("ifStatement_2 completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void ifStatement_3(){
try {
CharStream stream =
new NoCaseStringStream("if p.Name = deletedName then\n" +
" -- This is the one. Delete it.\n" +
" self.PaintingData.DeleteRow(p);\n" +
" exit;\n" +
" end if;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("ifStatement_3 completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void ifStatement_4(){
try {
CharStream stream =
new NoCaseStringStream("if (a = b) and bob then\n" +
// "x = y;" +
"end if;");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("ifStatement_4 completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void ifStatement_5(){
try {
CharStream stream =
new NoCaseStringStream(
" if (PreferenceList[i].WindowName.ToUpper().Value = pWindow) \r\n" +
" AND (PreferenceList[i].PreferenceName.ToUpper().Value = pPreferenceName) " +
" then\r\n" +
" PreferenceList[i].PreferenceValue.SetValue(pPreferenceValue);\r\n" +
" ReturnObj = PreferenceList[i].Clone(TRUE);\r\n" +
" found = TRUE;\r\n" +
" exit;\r\n" +
" end if;\r\n");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("ifStatement_5 completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void startTaskStatement_simple(){
try {
CharStream stream =
new NoCaseStringStream("start task theBid.StartBid();\n");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("startTaskStatement_simplest completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void startTaskStatement_Event(){
try {
CharStream stream =
new NoCaseStringStream("start task theBid.StartBid(\n" +
" bidderName = theUserName,\n" +
" bidValue = theBidValue,\n" +
" lastBidTime = theLastBidTime,\n" +
" bidInProgress = theBidInProgress)\n" +
" where completion = event;\n");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("startTaskStatement_simple completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void startTaskStatement_Event_Transaction(){
try {
CharStream stream =
new NoCaseStringStream("start task self.theBid.StartBid(\n" +
" bidderName = self.theUserName,\n" +
" bidValue = self.theBidValue,\n" +
" lastBidTime = self.theLastBidTime,\n" +
" bidInProgress = self.theBidInProgress)\n" +
" where completion = event, transaction = dependent;\n");
ForteLexer lexer = new ForteLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
ForteParser parser = new ForteParser(tokenStream);
parser.statement();
int errors = parser.getNumberOfSyntaxErrors();
if (errors > 0){
Assert.fail("startTaskStatement completed with " + errors + " errors");
}
} catch (RecognitionException e) {
Assert.fail(e.getMessage());
}
}
@Test
public void beginTransactionStatement() throws IOException, RecognitionException{
testStatement("block",
"begin transaction do\n" +
" -- Specify some output parameters, even though \n" +
" -- they will not be filled in here, but will be \n" +
" -- filled in on the StartBid_return event.\n" +
" ptg : Painting;\n" +
" bidding_task : TaskDesc;\n" +
" bidding_task = start task self.theBid.StartBid(\n" +
" bidderName = self.theUserName,\n" +
" bidValue = self.theBidValue,\n" +
" lastBidTime = self.theLastBidTime,\n" +
" bidInProgress = self.theBidInProgress)\n" +
" where completion = event, transaction = dependent;\n" +
" theMessage = 'Waiting for bid to become available.';\n" +
"\n" +
" event loop\n" +
" when self.theBid.StartBid_return (\n" +
" nvalue = bidValue, ntime = lastBidTime,\n" +
" nprogress = bidInProgress, nname = return) do\n" +
" -- The lock has been granted. \n" +
" -- Now let the OK button\n" +
" -- and updates on the bid amount be allowed.\n" +
" theMessage = 'Bid lock granted to you.';\n" +
" \n" +
" <IncreaseButton>.State = FS_UPDATE;\n" +
" <OKButton>.State = FS_UPDATE;\n" +
"\n" +
" -- Set the data again (just to be sure).\n" +
" self.theOriginalBidValue = nvalue;\n" +
" self.theBidValue = nvalue;\n" +
" self.theLastBidTime.SetValue(ntime);\n" +
" self.theBidInProgress = nprogress;\n" +
" self.hasBidLock = TRUE;\n" +
"\n" +
" when self.theBid.StartBid_exception (e = exception) \n" +
" do\n" +
" -- Add the exception to the errors for this task, \n" +
" -- and then re-raise the exception to get out.\n" +
" task.ErrorMgr.AddError(GenericException(e));\n" +
" raise e;\n" +
"\n" +
" -- Process the button clicks that might occur\n" +
" when <OKButton>.Click do\n" +
" -- This completes the bid, commits the \n" +
" -- transaction and gets out.\n" +
" self.theBid.CompleteBid (bid = theBidValue);\n" +
" exit;\n" +
"\n" +
" when task.Shutdown do\n" +
" if self.hasBidLock then\n" +
" post self.theBid.BidCancelled;\n" +
" self.theBidValue = self.theOriginalBidValue;\n" +
" end if;\n" +
" transaction.Abort(TRUE);\n" +
" exit;\n" +
"\n" +
" when <CancelButton>.Click do\n" +
" -- This cancels the bid by aborting the \n" +
" -- transaction. This will drop out of the event \n" +
" -- loop and into the exception section of the \n" +
" -- transaction.\n" +
" if self.hasBidLock then\n" +
" post self.theBid.BidCancelled;\n" +
" self.theBidValue = self.theOriginalBidValue;\n" +
" end if;\n" +
" transaction.Abort(TRUE);\n" +
" exit;\n" +
"\n" +
" when <IncreaseButton>.Click do\n" +
" -- Increase by the minimum.\n" +
" self.theBidValue = self.theBidValue + 50000;\n" +
"\n" +
" -- Process the update events on the data.\n" +
" when self.theBid.BidCompleted (nBid = newBid, \n" +
" tBid = timeOfBid, wBid = whoBid) do\n" +
" self.theOriginalBidValue = nBid;\n" +
" self.theBidValue = nBid;\n" +
" self.theLastBidTime.SetValue(tBid);\n" +
" self.theLastBidder = wBid;\n" +
" -- If this is the last concurrent bidder, the \n" +
" -- GotLock event will arrive right after this.\n" +
" end event;\n" +
"\n" +
"exception -- For the transaction\n" +
" when e : GenericException do\n" +
" -- Transaction is aborted. Get out.\n" +
" task.ErrMgr.ShowErrors(TRUE);\n" +
"\n" +
" when e : AbortException do\n" +
" task.ErrMgr.Clear(); -- Do not show errors.\n" +
"end transaction; -- Commits transaction.\n" +
"");
}
@Test
public void sqlSelect() throws IOException, RecognitionException{
testStatement("SQl select",
"sql select * into :painter\n" +
" from ArtistTab\n" +
" where Name like :name\n" +
" on session self.MGRSession;");
}
@Test
public void sqlImmediate() throws IOException, RecognitionException{
testStatement("SQl immediate",
"sql execute immediate \n" +
" 'create table ArtistTab(Name varchar(30) not null, Country varchar(30) not null, Comments varchar(200) not null)'\n" +
" on session self.MGRSession;\n" +
"");
}
@Test
public void sqlInsert() throws IOException, RecognitionException{
testStatement("SQl insert",
"sql insert into ArtistTab values (:artists) \n" +
" on session self.MGRSession;");
}
@Test
public void sqlOpenCursor() throws IOException, RecognitionException{
testStatement("SQl open cursor",
"sql open cursor blobCurs(name) on session self.MGRSession;");
}
@Test
public void sqlFetchCursor() throws IOException, RecognitionException{
testStatement("SQl fetch cursor", "sql fetch cursor blobCurs into :binData;" );
}
@Test
public void sqlCloseCursor() throws IOException, RecognitionException{
testStatement("SQl close cursor", "sql close cursor blobCurs;");
}
}