1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2004 Kevin Rogers
4   //
5   // This file is part of MillScript.
6   //
7   // MillScript is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
20  ////////////////////////////////////////////////////////////////////////////////
21  package org.millscript.millscript.vm;
22  
23  import org.millscript.millscript.conf.ApiConf;
24  import org.millscript.millscript.functions.Function;
25  
26  import junit.framework.TestCase;
27  
28  /**
29   * Tests the FunctionCall operation.
30   */
31  public class FunctionCallTest extends TestCase {
32  
33      /**
34       * Test function which returns the first argument it's passed and discards
35       * any others. This can be used to test argument passing in general and the
36       * <code>invoke1</code> method.
37       */
38      private class ReturnFirstArgFunction extends Function {
39  
40          /* (non-Javadoc)
41           * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
42           */
43          @Override
44          public void apply( final Machine mc, final int nargs) {
45              // We take any number of arguments
46              checkNargsGT( mc, 1, nargs );
47  
48              final Object firstArg = mc.popObject();
49              // We start i counting from 1 because we've already removed the
50              // first argument
51              for( int i = 1; i < nargs; i++ ) {
52                  mc.popObject();
53              }
54  
55              mc.pushObject( firstArg );
56          }
57  
58      }
59  
60      /**
61       * Test function which returns the last argument it's passed and discards
62       * any others. This can be used to test argument passing in general and the
63       * <code>invoke1</code> method.
64       */
65      private class ReturnLastArgFunction extends Function {
66  
67          /* (non-Javadoc)
68           * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
69           */
70          @Override
71          public void apply( final Machine mc, final int nargs) {
72              // We take any number of arguments
73              checkNargsGT( mc, 1, nargs );
74  
75              // We start i counting from 1 because we want to pop all but one of
76              // the arguments off the stack.
77              for( int i = 1; i < nargs; i++ ) {
78                  mc.popObject();
79              }
80  
81              // We've poped all but the last argument from the machine, so
82              // we don't need to do anything to return it.
83              // i.e. we could pop it and push it straight back!
84          }
85  
86      }
87  
88      /**
89       * Test function which discards any arguments it's passed. This can be used
90       * to test argument passing in general and the <code>invoke1</code> method.
91       */
92      private class SwallowArgsFunction extends Function {
93  
94          /* (non-Javadoc)
95           * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
96           */
97          @Override
98          public void apply( final Machine mc, final int nargs ) {
99              for( int i = 0; i < nargs; i++ ) {
100                 mc.popObject();
101             }
102         }
103 
104     }
105 
106     /**
107      * Constructor for FunctionCallTest.
108      *
109      * @param arg0
110      */
111     public FunctionCallTest( String arg0 ) {
112         super( arg0 );
113     }
114 
115     /**
116      * Executes <code>ReturnFirstArgFunction</code>, checking if function
117      * application is working.
118      */
119     public void testReturnFirstArg() {
120         final Engine engine = new Engine( new ApiConf() );
121         FunctionCall fc = engine.newFunctionCall( new ReturnFirstArgFunction() );
122         fc.addArg( "hello" );
123         fc.addArg( "there" );
124         final Object result = fc.invoke1();
125         assertTrue( result instanceof String );
126         assertEquals( "hello", result );
127     }
128 
129     /**
130      * Executes <code>ReturnLastArgFunction</code>, checking if function
131      * application is working.
132      */
133     public void testReturnLastArg() {
134         final Engine engine = new Engine( new ApiConf() );
135         FunctionCall fc = engine.newFunctionCall( new ReturnLastArgFunction() );
136         fc.addArg( "hello" );
137         fc.addArg( "there" );
138         final Object result = fc.invoke1();
139         assertTrue( result instanceof String );
140         assertEquals( "there", result );
141     }
142 
143     /**
144      * Executes <code>SwallowArgFunction</code>, checking if function
145      * application is working. This checks that <code>invoke0</code> is
146      * working as expected.
147      */
148     public void testSwallowArgs() {
149         final Engine engine = new Engine( new ApiConf() );
150         FunctionCall fc = engine.newFunctionCall( new SwallowArgsFunction() );
151         fc.addArg( "hello" );
152         fc.addArg( "there" );
153         fc.invoke0();
154     }
155 
156 }