1702 lines
47 KiB
Go
1702 lines
47 KiB
Go
|
// Copyright 2017-2018 DERO Project. All rights reserved.
|
||
|
// Use of this source code in any form is governed by RESEARCH license.
|
||
|
// license can be found in the LICENSE file.
|
||
|
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
|
||
|
//
|
||
|
//
|
||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
package dvm
|
||
|
|
||
|
import "fmt"
|
||
|
import "reflect"
|
||
|
import "testing"
|
||
|
|
||
|
//import "github.com/deroproject/derosuite/crypto"
|
||
|
|
||
|
var execution_tests = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"demo 1",
|
||
|
`Function TestRun(s Uint64) Uint64
|
||
|
10 Return s
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"s": "8"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
},
|
||
|
{
|
||
|
"invalid return expression",
|
||
|
`Function TestRun(s Uint64) Uint64
|
||
|
10 Return 1s
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"s": "8"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function with 2 params",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 + a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "4", "a2": "4"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function with 2 string params",
|
||
|
`Function TestRun(a1 String,a2 String) String
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 + a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "4", "a2": "4"},
|
||
|
nil,
|
||
|
Variable{Type: String, ValueString: "44"},
|
||
|
},
|
||
|
|
||
|
// test all arithmetic operations
|
||
|
{
|
||
|
"valid function testing substraction ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 - a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "12", "a2": "4"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing multiplication ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 * a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "4"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing division ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 / a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "25", "a2": "3"}, // it is 25 to confirm we are doing integer division
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing modulus ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 % a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "35", "a2": "9"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing SHL ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 << a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "4", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing SHR ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 >> a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "32", "a2": "2"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing OR ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 | a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "8", "a2": "8"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing AND ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 & a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "9", "a2": "10"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"valid function testing NOT ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return !a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "9", "a2": "10"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(18446744073709551606)}, //NOT 9 == 18446744073709551606
|
||
|
}, {
|
||
|
"valid function testing ^XOR ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return ^a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "9", "a2": "10"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(18446744073709551606)}, //NOT 9 == 18446744073709551606
|
||
|
}, {
|
||
|
"valid function testing XOR ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 ^ a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "60", "a2": "13"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(49)},
|
||
|
}, {
|
||
|
"valid function testing || ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 || a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "0", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"valid function testing && 1 ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 && a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "0", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(0)},
|
||
|
}, {
|
||
|
"valid function testing && 2",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return (a1 && a2)
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"valid function testing && 3",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return 0 || (a1 && a2)
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing LET ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing IF THEN form1 fallthrough",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing IF THEN form1 THEN case",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(0)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing IF THEN ELSE form1 THEN case",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30 ELSE GOTO 20
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(0)},
|
||
|
}, {
|
||
|
"valid function testing IF THEN ELSE form1 ELSE case",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30 ELSE GOTO 20
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing != success ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 != 3 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing != failed",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 != 3 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "3", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"valid function testing <> ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 <> 3 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"invalid operator testing = ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 = 3 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing > success ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 > 1 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing > failed ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if 1 > a1 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing >= success",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 >= 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing >= failed",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 >= 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing < success ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 < 3 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing < failed ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 < 3 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "5", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing <= success ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 <= 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing <= success ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 <= 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "4", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing string == success",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 == a2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "asdf", "a2": "asdf"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing string == success",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 == "asdf" then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "asdf", "a2": "asdf"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing string == failed",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 == a2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "asdf", "a2": "asdf1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing !string success ",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if !a1 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "", "a2": "asdf1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing !string fail ",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if !a1 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "a1", "a2": "asdf1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing string != ",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 != a2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "asdf", "a2": "asdfz"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
}, {
|
||
|
"valid function testing LOR ",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 != a2 || a1 != a2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "asdf", "a2": "asdf"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing comparision of uint64 /string ",
|
||
|
`Function TestRun(a1 String,a2 String) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 LET s1 = 99
|
||
|
15 if a1 != s1 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "asdf", "a2": "asdfz"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(99)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"valid function arbitrary function evaluation",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 fact_recursive(10)
|
||
|
20 LET s1 = fact_recursive(10)
|
||
|
30 return s1
|
||
|
End Function
|
||
|
Function fact_recursive(s Uint64) Uint64
|
||
|
10 IF s == 1 THEN GOTO 20 ELSE GOTO 30
|
||
|
20 RETURN 1
|
||
|
30 RETURN s * fact_recursive(s -1)
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(3628800)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"Invalid function with 2 string params substractions",
|
||
|
`Function TestRun(a1 String,a2 String) String
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20
|
||
|
30 return a1 - a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "4", "a2": "4"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: String, ValueString: "44"},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests {
|
||
|
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ensure 100% coverage of IF
|
||
|
var execution_tests_if = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"valid function testing IF THEN form1 fallthrough",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing IF THEN form1 THEN case",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(0)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing IF THEN ELSE form1 THEN case",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30 ELSE GOTO 20
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "2", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(0)},
|
||
|
}, {
|
||
|
"valid function testing IF THEN ELSE form1 ELSE case",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30 ELSE GOTO 20
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"invalid function testing IF THEN form1 malformed if then",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 = != 2 thenn GOTO 30
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing IF THEN form1 malformed else",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 30 ELSEE GOTO 20
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing IF THEN form1 malformed then line number",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 0 ELSE GOTO 20
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing IF THEN form1 malformed then else number",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 20 ELSE GOTO 0
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing IF THEN form1 malformed unparseable then line number",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO ewr
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing IF THEN ELSE form1 malformed unparseable then line number",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO ewr ELSE GOTO 20
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing IF THEN form1 malformed unparseable else number",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 20 ELSE GOTO ewr
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing IF THEN form1 unknownelse number",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 if a1 == 2 then GOTO 20 ELSE GOTO 43535
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing IF THEN invalid IF expression",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
13 dim x1 as String
|
||
|
15 if x1 then GOTO 20 ELSE GOTO 43535
|
||
|
20 RETURN 2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "77", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_IF_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests_if {
|
||
|
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ensure 100% coverage of DIM
|
||
|
var execution_tests_dim = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"valid function testing DIM ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 GOTO 20
|
||
|
17 RETURN 0
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing DIM string",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as String
|
||
|
15 GOTO 30
|
||
|
17 RETURN 0
|
||
|
20
|
||
|
30 return a1 + a2
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid dim expression collision between arguments and local variable",
|
||
|
`Function TestRun(s Uint64) Uint64
|
||
|
10 dim s as Uint64
|
||
|
20
|
||
|
30 return 8
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"s": "8"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"invalid dim expression invalid variable name",
|
||
|
`Function TestRun(s Uint64) Uint64
|
||
|
10 dim 1s as Uint64
|
||
|
20
|
||
|
30 return 8
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"s": "8"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"invalid dim expression invalid 2nd variable name",
|
||
|
`Function TestRun(s Uint64) Uint64
|
||
|
10 dim s1,2s2 as Uint64
|
||
|
20
|
||
|
30 return 8
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"s": "8"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"invalid dim expression invalid dim syntax",
|
||
|
`Function TestRun(s Uint64) Uint64
|
||
|
10 dim tu ajs Uint64
|
||
|
20
|
||
|
30 return 8
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"s": "8"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
}, {
|
||
|
"invalid dim expression invalid dim syntax",
|
||
|
`Function TestRun(s Uint64) Uint64
|
||
|
10 dim tu as UUint64
|
||
|
20
|
||
|
30 return 8
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"s": "8"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(8)},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_DIM_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests_dim {
|
||
|
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ensure 100% coverage of LET
|
||
|
var execution_tests_let = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"valid function testing LET ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"valid function testing LET String",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
12 dim add1,add2 as String
|
||
|
13 let add1 = add2
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing LET ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20 LET
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing LET undefined local variable",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20 LET s3 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing LET malformed expression",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
20 LET s1 = ((a1) + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing LET putting int into string",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as String
|
||
|
20 LET s1 = (a1) + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_LET_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests_let {
|
||
|
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ensure 100% coverage of PRINT
|
||
|
var execution_tests_print = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"valid function testing PRINT ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15
|
||
|
17 PRINT "%d %d" s1 s2
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing PRINT ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15
|
||
|
17 PRINT "%d %d" a1 a2
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_PRINT_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests_print {
|
||
|
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// generic cases of coding mistakes
|
||
|
var execution_tests_generic = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"invalid function testing Generic case if function does not return ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15
|
||
|
17 PRINT "%d %d" s1 s2
|
||
|
20 LET s1 = a1 + a2
|
||
|
// 30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing Generic case if invalid expression evaluated ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15
|
||
|
17 dummy (s1 s2 s3
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing Generic case if valid expression but not a function call ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15
|
||
|
17 2 +3
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
|
||
|
// these case check callability of unexported functions etc
|
||
|
{
|
||
|
"valid function testing Invalid Rune ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
string([]byte{0x80}), // EntryPoint checking
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"valid function testing executing first non-ascii function ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"☺☻TestRun", // EntryPoint checking
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"valid function testing executing first non-letter function",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"1TestRun", // EntryPoint checking
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"valid function testing executing unexported function ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"testRun", // EntryPoint checking
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"invalid function testing executing non-existing function ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun1", // no function exists
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"valid function testing parameter missing ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a3": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"valid function testing Invalid parameter uint64 ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "-1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing use unknown variable ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1*a3
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"valid function testing use uint64 larger than 64 bits ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1* 118446744073709551615
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"valid function testing recursive FACTORIAL ",
|
||
|
`Function fact_recursive(s Uint64) Uint64
|
||
|
10 IF s == 1 THEN GOTO 20 ELSE GOTO 30
|
||
|
20 RETURN 1
|
||
|
30 RETURN s * fact_recursive(s -1)
|
||
|
End Function
|
||
|
Function TestRun(a1 Uint64) Uint64
|
||
|
10 dim result as Uint64
|
||
|
20 LET result = fact_recursive(a1)
|
||
|
60 printf "FACTORIAL of %d = %d" a1 result
|
||
|
70 RETURN result
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "10", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(3628800)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"invalid function testing paramter skipped ",
|
||
|
`Function fact_recursive(s Uint64) Uint64
|
||
|
10 IF s == 1 THEN GOTO 20 ELSE GOTO 30
|
||
|
20 RETURN 1
|
||
|
30 RETURN s * fact_recursive(s -1)
|
||
|
End Function
|
||
|
Function TestRun(a1 Uint64) Uint64
|
||
|
10 dim result as Uint64
|
||
|
20 LET result = fact_recursive()
|
||
|
60 printf "FACTORIAL of %d = %d" s result
|
||
|
70 RETURN result
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "10", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(3628800)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing unknown function called ",
|
||
|
`Function fact_recursive(s Uint64) Uint64
|
||
|
10 IF s == 1 THEN GOTO 20 ELSE GOTO 30
|
||
|
20 RETURN 1
|
||
|
30 RETURN s * fact_recursive(s -1)
|
||
|
End Function
|
||
|
Function TestRun(a1 Uint64) Uint64
|
||
|
10 dim result as Uint64
|
||
|
20 LET result = fact_recursive_unknown(a1)
|
||
|
60 printf "FACTORIAL of %d = %d" s result
|
||
|
70 RETURN result
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "10", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(3628800)},
|
||
|
},
|
||
|
{
|
||
|
"invalid function testing error withing sub function call",
|
||
|
`Function fact_recursive(s Uint64) Uint64
|
||
|
10 IF s == 1 THEN GOTO 20 ELSE GOTO 30
|
||
|
20 RETURN 1
|
||
|
30 RETURN s * fact_recursive(s -1) * (
|
||
|
End Function
|
||
|
Function TestRun(a1 Uint64) Uint64
|
||
|
10 dim result as Uint64
|
||
|
20 LET result = fact_recursive(a1)
|
||
|
60 printf "FACTORIAL of %d = %d" s result
|
||
|
70 RETURN result
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "10", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(3628800)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"1valid function testing sub function call without return",
|
||
|
`Function dummy(s Uint64)
|
||
|
|
||
|
20 RETURN
|
||
|
End Function
|
||
|
Function TestRun(a1 Uint64) Uint64
|
||
|
10 dim result as Uint64
|
||
|
20 LET result = a1
|
||
|
60 dummy(a1)
|
||
|
70 RETURN result
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "10", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(10)},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
"valid function testing recursive FACTORIAL ",
|
||
|
`Function fact_recursive(s Uint64, a String, b String, str String) Uint64
|
||
|
10 IF s == 1 THEN GOTO 20 ELSE GOTO 30
|
||
|
20 RETURN 1
|
||
|
30 RETURN s * fact_recursive(s -1,a,b,str)
|
||
|
End Function
|
||
|
Function TestRun(a1 Uint64,a String, b String, str String) Uint64
|
||
|
10 dim result as Uint64
|
||
|
20 LET result = fact_recursive(a1,a,b,str)
|
||
|
60 printf "FACTORIAL of %d = %d" a1 result
|
||
|
70 RETURN result
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "10", "a2": "1", "a": "address param", "b": "blob param", "str": "str_param"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(3628800)},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_Generic_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests_generic {
|
||
|
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ensure 100% coverage of RETURN
|
||
|
var execution_tests_return = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"valid function testing RETURN uint64 ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"valid function testing RETURN String ",
|
||
|
`Function TestRun(a1 String,a2 Uint64) String
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: String, ValueString: "1"},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing RETURN String ",
|
||
|
`Function TestRun(a1 String,a2 Uint64) String
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: String, ValueString: "1"},
|
||
|
}, {
|
||
|
"valid function testing non returning function returning nothing ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64)
|
||
|
30 return
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Invalid},
|
||
|
},
|
||
|
{
|
||
|
"valid function testing non returning function returning something ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64)
|
||
|
30 return a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueString: "1"},
|
||
|
}, {
|
||
|
"invalid function testing RETURN uint64 ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
}, {
|
||
|
"invalid function testing RETURN contains unparseable function ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
30 return ( a1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(1)},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_RETURN_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests_return {
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ensure 100% coverage of GOTO
|
||
|
var execution_tests_goto = []struct {
|
||
|
Name string
|
||
|
Code string
|
||
|
EntryPoint string
|
||
|
Args map[string]interface{}
|
||
|
Eerr error // execute error
|
||
|
result Variable // execution result
|
||
|
}{
|
||
|
{
|
||
|
"valid function testing GOTO ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 GOTO 20
|
||
|
17 RETURN 0
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
nil,
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing GOTO ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 GOTO qeee
|
||
|
17 RETURN 0
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing GOTO ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 GOTO
|
||
|
17 RETURN 0
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
}, {
|
||
|
"invalid function testing GOTO ",
|
||
|
`Function TestRun(a1 Uint64,a2 Uint64) Uint64
|
||
|
10 dim s1, s2 as Uint64
|
||
|
15 GOTO 0
|
||
|
17 RETURN 0
|
||
|
20 LET s1 = a1 + a2
|
||
|
30 return s1
|
||
|
End Function
|
||
|
`,
|
||
|
"TestRun",
|
||
|
map[string]interface{}{"a1": "1", "a2": "1"},
|
||
|
fmt.Errorf("dummy"),
|
||
|
Variable{Type: Uint64, ValueUint64: uint64(2)},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// run the test
|
||
|
func Test_GOTO_execution(t *testing.T) {
|
||
|
for _, test := range execution_tests_goto {
|
||
|
sc, _, err := ParseSmartContract(test.Code)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected nil\nActual %s\n", test.Name, err)
|
||
|
}
|
||
|
|
||
|
state := &Shared_State{Chain_inputs: &Blockchain_Input{}}
|
||
|
result, err := RunSmartContract(&sc, test.EntryPoint, state, test.Args)
|
||
|
switch {
|
||
|
case test.Eerr == nil && err == nil:
|
||
|
if !reflect.DeepEqual(result, test.result) {
|
||
|
t.Fatalf("Error while executing smart contract \"%s\"\nExpected result %v\nActual result %v\n", test.Name, test.result, result)
|
||
|
}
|
||
|
case test.Eerr != nil && err != nil: // pass
|
||
|
case test.Eerr == nil && err != nil:
|
||
|
fallthrough
|
||
|
case test.Eerr != nil && err == nil:
|
||
|
t.Fatalf("Error while parsing smart contract \"%s\"\nExpected %s\nActual %s\n", test.Name, test.Eerr, err)
|
||
|
}
|
||
|
}
|
||
|
}
|