test_true([["$Id: testsuite.in,v 1.542 2002/09/24 15:14:47 grubba Exp $"]]); |
|
// This triggered a bug only if run sufficiently early. |
test_compile_any([[#pike 7.2]]) |
|
cond([[all_constants()->_verify_internals]], |
[[ |
test_do(_verify_internals()) |
]]); |
test_eq(1e1,10.0); |
test_eq(1E1,10.0); |
test_eq(1e+1,10.0); |
test_eq(1.1e1,11.0); |
test_eq(1e-1,0.1); |
test_eq('\x20',32); |
test_eq("\x20","\040"); |
test_eq("\d32","\x20"); |
test_eq('Ã…',"Ã…"[0]); |
test_eq('\7777',"\7777"[0]); |
test_eq('\77777777',"\77777777"[0]); |
test_eq("\x10000","\x10000"); |
test_eq(0x80000000-0x80000000, 0); |
test_eq(0xf0000000-0xf0000000, 0); |
test_eq(0x80000001-0x80000000, 1); |
test_eq(0x80000000-0x80000001,-1); |
test_eq(-2147483648*-1, -2147483648/-1); |
test_true([[1.0e-40]]); |
test_eq([[#"foo |
bar"]],[["foo\nbar"]]); |
test_eq([[#"foo\ |
bar"]],[["foobar"]]); |
test_true([[stringp(#string "Makefile")]]); |
test_any([[class Bar { array(int) foo = ({}); }; |
class Foo { inherit Bar; array(int) foo = ({1}); }; |
return sizeof(Foo()->foo);]],1); |
|
test_eq(8, 0b1000); |
test_eq(-8, -0b1000); |
test_eq(16, 0b10000); |
test_eq(-16, -0b10000); |
|
test_do([[ |
// bug 2677 |
int x; |
if (time()) |
x = 1; |
else |
foo: break foo; |
]]) |
|
test_any([[ |
// bug 2690 |
array(function) foo(void|int b) |
{ |
int add() { return b++; }; |
return ({ add, add }); |
}; |
array(function) bar = foo(); |
return equal(({`==(@bar),@bar()}), ({ 1, 0, 1 })); |
]], 1) |
|
test_any([[ |
int f (int i) {i = 0; return i;}; |
return f (1); |
]],0) |
|
test_any([[ |
class X |
{ |
int Ack(int M, int N) { |
if (M == 0) return( N + 1 ); |
if (N == 0) return( Ack(M - 1, 1) ); |
return( Ack(M - 1, Ack(M, (N - 1))) ); |
} |
}; |
|
class Y { inherit X; }; |
|
return Y()->Ack(2,2); |
]],7) |
|
test_eval_error([[mixed x; return mkmapping(x,x)]]); |
|
test_eval_error([[class Foo { |
void bar() {} |
void foo() {destruct(this_object());bar();} |
}; |
Foo()->foo(); |
]]) |
|
test_do([[ |
void foo (int i) { |
multiset res = (<>); |
if (i) res = res; |
}; |
foo (1); |
]]) |
|
test_any([[ |
array tmp=({}); |
tmp=({([])})+tmp; |
tmp->foo=7; |
tmp=({([])})+tmp; |
return sizeof(tmp[0]); |
]], 0) |
|
|
test_any([[int a=0xffffffff; return a+17]], 0x100000010); |
test_any([[int a=0xffffffff; return a-17]], 0xffffffee); |
test_any([[int a=0xffffffff; return a*17]], 0x10ffffffef); |
test_any([[int a=0xffffffff; return a^17]], 0xffffffee); |
test_any([[int a=0xffffffff; return a&17]], 17); |
test_any([[int a=0xffffffff; return a|17]], 0xffffffff); |
test_any([[int a=0xffffffff; return a<<17]], 0x1fffffffe0000); |
|
test_any([[ int a=0xffffffff; return a/17 ]], |
[[ (0xffffffff == -1)?-1:0x0f0f0f0f ]]); |
test_any([[ int a=0xffffffff; return a%17 ]], |
[[ (0xffffffff == -1)?16:0 ]]); |
test_any([[ int a=0xffffffff; return a>>17 ]], |
[[ (0xffffffff == -1)?-1:0x7fff ]]); |
|
test_any([[return sprintf("%O", typeof(aggregate("foo")));]], "array(string)"); |
test_any([[int a; return sprintf("%O", typeof(aggregate(a)));]], "array(int)"); |
test_any([[int|string a; |
string s = sprintf("%O", typeof(aggregate(a))); |
return (< "array(string | int)", "array(int | string)" >)[s];]], 1); |
test_any([[return sprintf("%O", typeof(aggregate()));]], "array(zero)"); |
test_any([[int i; return (< "int", "int | zero", "zero | int" >) |
[sprintf("%O", typeof(max(i,0)))];]], 1) |
|
test_any([[array(string) a; return sprintf("%O", typeof(a[0])); ]], "string") |
|
test_any([[class foo { string a; }; |
object(foo) bar; |
return sprintf("%O", typeof(bar->a));]], "string"); |
|
test_any([[class foo { string a; }; |
array(object(foo)) bar; |
return sprintf("%O", typeof(bar[0]->a));]], "string"); |
|
test_any([[function(:string)|function(int:int) f; |
return sprintf("%O", typeof(f())); ]], |
"string") |
|
test_any([[function(:string)|function(int:int) f; |
return sprintf("%O", typeof(f(1))); ]], |
"int") |
|
test_any([[function(:string)|function(mixed, mixed...:int) f; |
return sprintf("%O", typeof(f())); ]], |
"string") |
|
test_any([[function(:string)|function(mixed, mixed ...:int) f; |
return sprintf("%O", typeof(f(1))); ]], |
"int") |
|
test_any([[mapping(object:string)|mapping(string:int) f; |
return sprintf("%O", typeof(f[class{}()])); ]], |
"string") |
|
test_any([[mapping(object:string)|mapping(string:int) f; |
return sprintf("%O", typeof(f[""])); ]], |
"int") |
|
test_any([[mapping(object:string)|mapping(string:int) f; |
return sort((sprintf("%O", typeof(f[0])) - " ")/"|")*"|"; ]], |
"int|string") |
|
test_any([[class Foo { string `[](mixed y) {return "";} }; |
object(Foo) foo; |
return sprintf("%O", typeof(foo[0])); ]], |
"string") |
|
test_any([[class Foo { array(int) _indices() {return ({0});} }; |
object(Foo) foo; |
return sprintf("%O", typeof(indices(foo))); ]], |
"array(int)") |
|
test_any([[class Foo { array(string) _values() {return ({""});} }; |
object(Foo) foo; |
return sprintf("%O", typeof(values(foo))); ]], |
"array(string)") |
|
test_any([[mapping(string:int) foo; |
array(string) bar; |
return sprintf("%O", typeof(rows(foo, bar))); ]], |
"array(int)") |
|
test_any([[{ |
class Foo |
{ |
mixed m; |
}; |
class Bar |
{ |
inherit Foo; |
string m; |
Foo b; |
mixed f() { |
return typeof(b->m); |
} |
}; |
Foo c; |
Bar d; |
return sprintf("%O$%O$%O$%O", |
Bar()->f(), typeof(c->m), typeof(d->m), typeof(d->b->m)); |
}]], "mixed$mixed$string$mixed") |
|
// type checks |
|
define(test_type_error, [[ |
test_compile_error([[ $1 x; x=$3; ]]) |
test_compile_error_any([[ class ErrBa { $1 x() { return $3; } } ]]) |
test_compile_error_any([[ class ErrBa { $1 x() { $2 a=$3; return a; } } ]]) |
]]) |
|
test_type_error(int,float,17.23) |
test_type_error(int,array,({1,2,3})) |
test_type_error(int,mapping,([1:2,3:4])) |
test_type_error(int,multiset,(<1,2,3>)) |
test_type_error(int,function,lambda() { return 17; }) |
test_type_error(int,program,object_program(this_object())) |
test_type_error(int,object,this_object()) |
|
test_type_error(float,int,17) |
test_type_error(float,array,({1,2,3})) |
test_type_error(float,mapping,([1:2,3:4])) |
test_type_error(float,multiset,(<1,2,3>)) |
test_type_error(float,function,lambda() { return 17; }) |
test_type_error(float,program,object_program(this_object())) |
test_type_error(float,object,this_object()) |
|
test_type_error(array,int,17) |
test_type_error(array,float,17.23) |
test_type_error(array,mapping,([1:2,3:4])) |
test_type_error(array,multiset,(<1,2,3>)) |
test_type_error(array,function,lambda() { return 17; }) |
test_type_error(array,program,object_program(this_object())) |
test_type_error(array,object,this_object()) |
|
test_type_error(mapping,int,17) |
test_type_error(mapping,float,17.23) |
test_type_error(mapping,array,({1,2,3})) |
test_type_error(mapping,multiset,(<1,2,3>)) |
test_type_error(mapping,function,lambda() { return 17; }) |
test_type_error(mapping,program,object_program(this_object())) |
test_type_error(mapping,object,this_object()) |
|
test_type_error(multiset,int,17) |
test_type_error(multiset,float,17.23) |
test_type_error(multiset,array,({1,2,3})) |
test_type_error(multiset,mapping,([1:2,3:4])) |
test_type_error(multiset,function,lambda() { return 17; }) |
test_type_error(multiset,program,object_program(this_object())) |
test_type_error(multiset,object,this_object()) |
|
test_type_error(function,int,17) |
test_type_error(function,float,17.23) |
test_type_error(function,array,({1,2,3})) |
test_type_error(function,mapping,([1:2,3:4])) |
test_type_error(function,multiset,(<1,2,3>)) |
|
test_type_error(program,int,17) |
test_type_error(program,float,17.23) |
test_type_error(program,array,({1,2,3})) |
test_type_error(program,mapping,([1:2,3:4])) |
test_type_error(program,multiset,(<1,2,3>)) |
|
test_type_error(object,int,17) |
test_type_error(object,float,17.23) |
test_type_error(object,array,({1,2,3})) |
test_type_error(object,mapping,([1:2,3:4])) |
test_type_error(object,multiset,(<1,2,3>)) |
|
test_compile_error([[ string a="abcb"; a=a/"b"; ]]) |
test_compile_error([[ string a="abcb"; a/="b"; ]]) |
test_compile_error([[ string a="abcb"; string b="b"; a=a/b; ]]) |
test_compile_error([[ string a="abcb"; string b="b"; a/=b; ]]) |
test_compile_error([[ string a="x"; int b; b="x"*17; ]]) |
test_compile_error([[ string a="x"; array b; b="x"*17; ]]) |
test_compile_error([[ int b=17; string a; a=b*42; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b/c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b/=c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b*c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b*=c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b+c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b+=c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b=b-c; ]]) |
test_compile_error([[ int b=17; float c=42.0; b-=c; ]]) |
test_compile_error([[ float b=17.0; string a; a=b*42; ]]) |
test_compile_error([[ float b=17.0; string a; a=b*42.0; ]]) |
|
test_compile_error([[class F {inherit master()->dirnode;};]]); |
|
// Warnings |
|
test_compile_warning([[ int *a ]]) |
test_compile_warning([[ int|float *a ]]) |
test_compile_warning([[ [mixed]1 ]]) |
|
// |
|
test_any([[ |
class Foo { |
constant zero = 0; |
mapping(string:array(int)) m; |
string foo() { return sprintf("%O", typeof(m[""][zero])); } |
}; |
return Foo()->foo(); |
]], "int") |
|
test_compile_any([[ |
class { ; } |
]]) |
|
test_compile_any([[ |
class { ; ; } |
]]) |
|
test_compile_any([[ |
class { ; constant c = 0; } |
]]) |
|
test_compile_any([[ |
class { void a() { constant c = 17; } |
void b() { constant c = 17; } } |
]]) |
|
test_compile_any([[ |
constant FOO = 0; |
mapping(int:string) foo = ([FOO: "foo"]); |
]]) |
|
test_compile_error([[ |
function(...:int) foo; |
]]); |
|
test_compile_error([[ |
function(,...:int) foo; |
]]); |
|
test_compile_error([[ |
function(string,...:int) foo; |
]]); |
|
test_any([[return class Z { |
string bonk() { return "oiff"; } |
|
class A |
{ |
string bonk_me() { return bonk(); } |
} |
|
class B { inherit A; } |
|
class C |
{ |
string oiff() { return "bonk"; } |
class D { inherit B; } |
} |
}()->C()->D()->bonk_me()]],"oiff") |
|
test_compile_error([[ |
class A { constant q = "x"; } |
class B { inherit A; string z="z"; constant q="x"+z; } |
]]) |
|
test_compile_any([[ |
class A |
{ |
object x(int y) |
{ |
return B(y); |
} |
} |
|
class B |
{ |
void create(int y) |
{ |
} |
} |
]]) |
|
// Test that prototypes evaluate to false. |
test_any([[ |
class Foo |
{ |
int foo(); |
int(0..1) f() |
{ |
return !foo; |
} |
}; |
return Foo()->f(); |
]], 1) |
|
test_any([[ |
class Foo |
{ |
int foo(); |
}; |
return !Foo()->foo; |
]], 1) |
|
test_do([[ |
class Foo |
{ |
inherit Stdio.File; |
|
void create() { } |
}; |
|
class Bar |
{ |
int y; |
|
|
class Gazonk |
{ |
inherit Foo; |
|
|
void create(Stdio.File f) |
{ |
assign(f); |
} |
} |
|
void create() |
{ |
Gazonk(Stdio.stdin); |
} |
}; |
|
Bar(); |
|
]]) |
|
test_any([[ |
object f = class { |
array recursive(mixed func, array data, mixed ... args) |
{ |
array ret=({}); |
|
foreach(data, mixed foo) |
{ |
if(arrayp(foo)) |
{ |
ret+=({ recursive(func, foo, @args) }); |
}else{ |
ret+=({ foo }); |
} |
} |
|
return func(ret, @args); |
}; |
}(); |
|
mixed x = ({ "A", ({}) }); |
x = f->recursive(replace, x, "B", ({})); |
|
for(int i = 0; i < sizeof(x); i++) { |
if (!stringp(x[i]) && !arrayp(x[i])) return 0; |
} |
return 1; |
]], 1); |
|
test_compile_error( [[ |
// This triggs a compiler bug on old Pike 7.3. |
non_existant(17) { |
return 0; |
} |
]]) |
|
test_any( [[ |
// bug [2861] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=2861 |
return mktime(0,0,0,1,0,70,0,0); |
]], 0) |
|
test_any( [[ |
// bug [2845] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=2845 |
return !catch{ String.Buffer()->add("x",0); }; |
]], 0) |
|
test_any( [[ |
// bug [2830] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=2830 |
class User{}; |
|
object luser = User(); |
|
#if constant(Pike.Security) |
object luser_creds = Pike.Security.Creds(luser, 0, 0); |
return !catch { |
return !!call_with_creds(luser_creds, Stdio.File, "/dev/null"); |
}; |
#endif |
return 0; |
]], 0 ) |
|
test_any( [[ |
// bug [1996] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=1996 |
class Implementation |
{ |
int foo() { return 1; } |
}; |
class Prototype |
{ |
int foo(); |
int bar() { return foo(); } |
}; |
class Test |
{ |
inherit Implementation; |
inherit Prototype; |
int test() { return bar(); } |
}; |
return Test()->test(); |
]], 1 ); |
|
test_any( [[ |
// bug [721] ------------------------------------------------------------- |
// http://community/crunch/show_bug.cgi?id=721 |
int res=0; |
program p; |
catch |
{ |
add_constant("test_a",compile_string("int foo();","test_a")); |
add_constant("test_b",compile_string("int foo();","test_b")); |
add_constant("test_c",compile_string( |
"inherit test_a;\n" |
"inherit test_b;\n" |
"final int foo() { return 1; }\n","test_c")); |
res=compile_string("inherit test_c;\n","test_d")()->foo(); |
}; |
return res; |
]],1); |
|
test_any( [[ |
// bug [1858] ------------------------------------------------------------ |
// http://community/crunch/show_bug.cgi?id=1858 |
string s=#" |
constant foo=({this_object()}); |
int|string test() |
{ |
if (!foo[0]) return sprintf(\"foo is %O\\n\",foo)-\"\\n\"; |
if (foo[0]==this_object()) return 1; |
return sprintf(\"foo is %O\\n\",foo)-\"\\n\"; |
} |
"; |
class handler { void compile_error(string file, int line, string err) { }}; |
catch { |
program p=compile_string(s,"test",handler()); |
return p()->test(); |
}; |
return 1; // compile error is ok |
]],1); |
|
// ----------------------------------------------------------------------- |
|
|
|
// This test checks for excessive recursion in |
// destruct_objects_to_destruct, and also that it keeps the destruct |
// order sane. |
test_do([[ |
class Top |
{ |
int count = 0; |
|
class Foo |
{ |
int c; |
object foo; |
static void create(object o) |
{ |
foo = o; |
c = count++; |
} |
|
void destroy() |
{ |
count--; |
if (count != c) |
error ("Destruct out of sequence, " |
"%d destructed when %d should be.\n", c, count); |
object x = foo && Foo(0); |
x = 0; |
// Cause call to destruct_objects_to_destruct. |
for (int j = 0; j < 10; j++) werror (""); |
} |
} |
|
mixed eat_stack() |
{ |
mixed err = 1; |
if (catch (err = eat_stack()) || err != 10) |
return intp (err) && err > 0 ? err + 1 : err; |
if (err = catch { |
|
Foo foo; |
for(int i=0; i < 10000; i++) |
foo = Foo(foo); |
foo = 0; |
// Cause call to destruct_objects_to_destruct. |
for (int j = 0; j < 10; j++) werror (""); |
|
}) return err; |
} |
|
static void create() |
{ |
if (mixed err = eat_stack()) { |
catch (err[1] = err[1][sizeof (err[1]) - 50..]); |
throw (err); |
} |
} |
}; |
|
Top(); |
]]); |
|
// Testing stack popping in the tail recursion opcodes |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
object key = monitor::lock(); |
return f (1); // F_CALL_LFUN_AND_RETURN |
}; |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
mixed g = f; |
int a() |
{ |
object key = monitor::lock(); |
return g (1); // F_CALL_FUNCTION_AND_RETURN |
} |
]]); |
test_program([[ |
Thread.Mutex monitor = Thread.Mutex(); |
int f (int x) |
{ |
if(monitor->trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
add_constant ("f", f); |
add_constant ("monitor", monitor); |
return compile_string(#" |
int g() |
{ |
object key = monitor->lock(); |
return f (1); // F_APPLY_AND_RETURN |
}")()->g(); |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (iter == 1) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
object key = monitor::lock(); |
iter = 1; |
return a (1); // F_COND_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
object key = monitor::lock(); |
iter = 2; |
return a (1); // F_TAIL_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
object key = monitor::lock(); |
iter = 2; |
int res = a (1); // F_RECUR |
iter = -1; |
return res; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
iter = 0; |
iter = x; |
} |
else { |
object key = monitor::lock(); |
iter = 2; |
a (1); // F_RECUR_AND_POP |
return iter; |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) |
return f (1); // F_CALL_LFUN_AND_RETURN |
}; |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int f (int x) |
{ |
if(monitor::trylock(1)) |
return 0; |
return x; |
}; |
mixed g = f; |
int a() |
{ |
foreach (({0, monitor::lock()}), mixed m) |
return g (1); // F_CALL_FUNCTION_AND_RETURN |
} |
]]); |
test_program([[ |
Thread.Mutex monitor = Thread.Mutex(); |
int f (int x) |
{ |
if(monitor->trylock(1)) |
return 0; |
return x; |
} |
int a() |
{ |
add_constant ("f", f); |
add_constant ("monitor", monitor); |
return compile_string(#" |
int g() |
{ |
foreach (({0, monitor->lock()}), mixed m) |
return f (1); // F_APPLY_AND_RETURN |
}")()->g(); |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (iter == 1) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
iter = 1; |
foreach (({0, monitor::lock()}), mixed m) |
return a (1); // F_COND_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
iter = 2; |
foreach (({0, monitor::lock()}), mixed m) |
return a (1); // F_TAIL_RECUR |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
return 0; |
return x; |
} |
else { |
iter = 2; |
int res; |
foreach (({0, monitor::lock()}), mixed m) { |
res = a (1); // F_RECUR |
iter = random (res); |
return res; |
} |
} |
} |
]]); |
test_program([[ |
inherit Thread.Mutex : monitor; |
int iter = 0; |
int a (void|int x) |
{ |
if (!iter) { |
iter = 1; |
return a (x); |
} |
else if (iter == 2) { |
if (monitor::trylock(1)) |
iter = 0; |
iter = x; |
} |
else { |
iter = 2; |
foreach (({0, monitor::lock()}), mixed m) { |
a (1); // F_RECUR_AND_POP |
return iter; |
} |
} |
} |
]]); |
|
test_false([[object_variablep(class X { int y; int z() { return 1; }}(),"foo")]]) |
test_false([[object_variablep(class X { int y; int z() { return 1; }}(),"z")]]) |
test_true([[object_variablep(class X { int y; int z() { return 1; }}(),"y")]]) |
|
test_any([[ int a,b; [a,b]=({1,2}); return a]],1) |
test_any([[ int a,b; [a,b]=({1,2}); return b]],2) |
test_any([[ int a,b; [ [a],b]=({ ({ 1 }) ,2}); return a]],1) |
test_any([[ int a,b; [ [a],b]=({ ({ 1 }) ,2}); return b]],2) |
test_any([[ int a; catch { [a]=({1,2}); }; return 1]],1) |
test_any([[ int a,b; catch { [a,b]=({1}); }; return 1]],1) |
test_any([[ mapping m=([]); m[m]=m; return stringp(sprintf("%O",m)); ]],1) |
dnl test_any([[ |
dnl // don't know if this /should/ be valid /Mirar |
dnl // remove if it shouldn't |
dnl |
dnl // I see no reason this should be allowed - Hubbe |
dnl |
dnl array a=({}); |
dnl []=a; return 1; ]],1) |
|
test_any([[ |
int q() { throw(1); }; |
catch { |
return q(); |
}; |
return 17; |
]],17) |
|
test_any([[ |
return class |
{ |
int q() { throw(1); }; |
int p() { |
catch { |
return q(); |
}; |
return 17; |
} |
}()->p(); |
]],17) |
|
test_compile_error([[ |
static function foo(string ...:object); |
int bar() |
{ |
return 17; |
} |
]]) |
test_compile_error([[ |
array a; |
a = path_info[..(sizeof(path_info)-2]*"/"; |
]]) |
test_compile_error([[ default ; ]]) |
test_compile_error([[ 0999; ]]) |
test_compile_error([[ int a,b; [a,b]++; ]]) |
test_compile_error([[ |
array(int) x; |
|
string foo() |
{ |
return "foo "+(array(string) x) * ","; |
} |
|
int main() |
{ |
return 0; |
} |
]]) |
|
dnl |
dnl this_program |
dnl |
|
test_true(this_program) |
test_any([[int this_program; return this_program;]], 0) |
test_any([[class A { int a() { return this_program == A; }}; return A()->a();]], 1) |
test_program([[ |
class A (int v) |
{ |
this_program clone() {return this_program (v);} |
} |
int a() {return A (4)->clone()->v == 4;} |
]]) |
test_program([[ |
int i = 17, j = 18; |
class A (int v) |
{ |
this_program clone() {return this_program (i);} |
} |
int a() {return A (4)->clone()->v == 17;} |
]]) |
test_program([[ |
class A (int v) |
{ |
this_program clone() {return this_program (j);} |
} |
int i = 17, j = 18; |
int a() {return A (4)->clone()->v == 18;} |
]]) |
test_program([[ |
int i = 17, v; |
this_program clone() {return this_program (i);} |
void create (int v_) {v = v_;} |
int a() {return clone()->v == 17;} |
]]) |
test_program([[ |
this_program clone() {return this_program (i);} |
int i = 17, v; |
void create (int v_) {v = v_;} |
int a() {return clone()->v == 17;} |
]]) |
test_program([[ |
class A {this_program clone() {return this_program();}} |
class B {inherit A;} |
// It would perhaps be nice if this_program possessed the magic |
// to refer to B in the inherit from A, but that would be magic indeed. |
int a() {return object_program (B()->clone()) == A;} |
]]) |
|
test_program([[ |
class A { |
class B { |
mixed f() { |
return ({global::this_program, |
A::this_program, // Works, but not really useful. |
B::this_program, // Ditto. |
::this_program, // Should perhaps be an error? /mast |
this_program}); |
} |
} |
} |
int a() { |
return equal (A()->B()->f(), ({object_program (this_object()), A, A.B, 0, A.B})); |
} |
]]) |
|
test_program([[ |
class A { |
class B { |
constant this_program = "foo"; |
mixed f (int this_program) { |
return ({A::this_program, B::this_program, this_program}); |
} |
} |
} |
int a() { |
return equal (A()->B()->f (1), ({A, "foo", 1})); |
} |
]]) |
|
test_program([[ |
class I { |
string this_program = "foo"; |
} |
class A { |
class B { |
inherit I; |
mixed f (int this_program) { |
return ({A::this_program, B::this_program, this_program}); |
} |
} |
} |
int a() { |
return equal (A()->B()->f (1), ({A, "foo", 1})); |
} |
]]) |
|
test_program([[ |
string this_program = "foo"; |
class A { |
class B { |
mixed f() { |
return ({A::this_program, B::this_program, this_program}); |
} |
} |
} |
int a() { |
return equal (A()->B()->f(), ({A, A.B, "foo"})); |
} |
]]) |
|
test_compile_error_any([[ |
class A {} |
class B { |
inherit A; |
mixed f() {return A::this_program;} |
} |
]]) |
|
dnl test_compile_error(0()) |
test_compile_error(1()) |
test_compile_error(""()) |
test_compile_error(([])()) |
test_compile_error(([])()) |
test_any([[ class X { int y; class Z { void destroy() { y++; } } }; X x=X(); destruct(x->Z()); return x->y;]],1) |
|
test_eval_error([[ class Z { int destroy() { return 1/y; } }(); ]]) |
|
test_any([[ class X { int y; class Z { static void destroy() { y++; } } }; X x=X(); destruct(x->Z()); return x->y;]],1) |
test_any([[ class X { int y; class Z { static void create() { y++; } } }; X x=X(); destruct(x->Z()); return x->y;]],1) |
|
cond([[all_constants()->_debug]], |
[[ |
test_do(_debug(_debug(0))) |
]]) |
test_do(_static_modules()) |
test_compile_any([[import Stdio; class x { string y() { read_file("foo"); } }]]) |
|
dnl ---------------------------------------------------------------- |
dnl backtrace/linenumber tests |
dnl ---------------------------------------------------------------- |
|
test_any([[ |
program p=compile_string( |
"int foo()\n" |
"{\n" |
" error(\"test error\\n\"); // line 3\n" |
" return 17;\n" |
"}","test"); |
mixed err=catch { p()->foo(); }; |
if (err[1][-1][1]!=3) |
{ |
werror("backtrace is:\n"+master()->describe_backtrace(err)); |
} |
return err[1][-1][1]; |
]],3); |
|
// Bug 2660 |
test_any([[ |
int foo(mixed a, mixed ... b) { |
return sizeof(backtrace()[-1]) - (3 + 1 + sizeof(b)); |
}; |
return foo(1,2,3,4)|foo(1); |
]], 0) |
|
define(test_backtrace_line_charset, [[ |
test_any([[ |
program p=compile_string( |
Locale.Charset.encoder("]]$1[[")->feed( |
"#charset ]]$1[[\n" |
"int foo()\n" |
"{\n" |
" error(\"test error\\n\"); // line 3\n" |
" return 17;\n" |
"}")->drain(),"test"); |
mixed err=catch { p()->foo(); }; |
if (err[1][0][1]!=3) |
{ |
werror("backtrace is:\n"+master()->describe_backtrace(err)); |
} |
return err[1][0][1]; |
]],3); |
]]) |
dnl test_backtrace_line_charset(utf-7) |
|
test_program([[ |
class X |
{ |
static void create (int i) |
{ |
if (i) |
error ("foo\n"); // Line 7 |
} |
} |
|
int f() |
{ |
X (0); |
X (1); // Line 14 |
} |
|
int a() |
{ |
array bt = catch (f())[1]; |
int ok = 0; |
foreach (reverse (bt), object ent) |
switch (functionp (ent[2]) && function_name (ent[2])) { |
case "create": if (ent[1] == 7) ok++; break; |
case "f": if (ent[1] == 14) ok++; break; |
} |
return ok == 2; |
} |
]]) |
|
test_program([[// [bug 3060] |
void x (mixed val) |
{ |
} |
|
class X |
{ |
void create() {error ("foo\n");} // Line 8 |
} |
|
object rx = class {}(); |
|
int y() |
{ |
x (rx->x); |
rx = X(); // Line 16 |
} |
|
int a() |
{ |
mixed bt = catch (y())[1]; |
int ok = 0; |
foreach (reverse (bt), object ent) |
switch (functionp (ent[2]) && function_name (ent[2])) { |
case "create": if (ent[1] == 8) ok++; break; |
case "y": if (ent[1] == 16) ok++; break; |
} |
return ok == 2; |
} |
]]) |
|
dnl Note: This line number error tend to go away with more debug. |
test_program([[ |
int x = 0; |
int y = [int] backtrace()[-1][1]; |
int a() {return y == 3;} |
]]) |
|
dnl ---------------------------------------------------------------- |
dnl scopes and stuff |
dnl ---------------------------------------------------------------- |
|
dnl |
dnl Undocumented but important behaviour... |
dnl |
test_eq([[Stdio._stdin]],[[Stdio.stdin->_fd]]) |
|
test_program([[ |
class A { |
string f() {return "A";} |
} |
class B { |
string f() {return "B";} |
} |
class C { |
inherit B; |
} |
class D { |
inherit A; |
inherit C; |
string g() {return f();} |
} |
int a() { |
return D()->g() == "B"; |
} |
]]) |
test_program([[ |
class A { |
string f() {return "A";} |
} |
class B { |
string f() {return "B";} |
} |
class C { |
inherit B; |
} |
class D { |
inherit C; |
inherit A; |
string g() {return f();} |
} |
int a() { |
return D()->g() == "A"; |
} |
]]) |
test_program([[ |
class A { |
string f() {return "A";} |
} |
class B { |
string f() {return "B";} |
} |
class C { |
inherit B; |
} |
class D { |
string f() {return "D";} |
inherit A; |
inherit C; |
string g() {return f();} |
} |
int a() { |
return D()->g() == "D"; |
} |
]]) |
|
test_compile_any([[ |
class Bar |
{ |
int f() {return 17;} |
|
class Foo { |
int g() {return f();} |
} |
|
inherit Foo; |
} |
]]) |
test_compile_any([[ |
class Bar |
{ |
int f() {return 17;} |
|
class Foo { |
int g() {return f();} |
} |
} |
|
class Gnu |
{ |
inherit Bar; |
inherit Foo; |
} |
|
]]) |
|
dnl Bug 2571 |
test_any([[ |
int var; |
void x() {var++;}; |
lambda () {x();}(); |
return var; |
]], 1); |
|
test_any([[ |
Stdio.write_file("testsuite_test.pmod", |
#" |
// this crashes Pike /Mirar 2001-05-19 |
// I haven't been able to minimize it futher, |
// and it needs to be in a separate module. |
|
mapping es=0; |
|
string efoo(string e) |
{ |
if (!es) |
{ |
mapping res=([]); |
|
string l; |
|
if (sscanf(l,\"%s%s\",string ext,string type)==4 && |
ext!=\"\" && ext[0]!=\"#\") // note the type error |
res[ext]=type; |
|
es=res; |
} |
} |
"); |
|
// Compilation handler that hides compilation errors. |
class handler |
{ |
void compile_error(string file, int line, string err) |
{ |
// werror("file: %O, line: %O, err: %O\n", file, line, err); |
} |
}; |
|
// turn this on when the bug is found |
// master()->set_inhibit_compile_errors(lambda(){}); |
|
//_optimizer_debug(2); |
//_assembler_debug(20); |
|
object orig_master = master(); |
replace_master(object_program(orig_master)()); |
catch { |
compile_string("import \".\";\n" |
"int foo() { testsuite_test.efoo; }\n", |
"testsuite_test", handler()); |
}; |
replace_master(orig_master); |
return 0; |
]],0); |
|
test_any([[ |
// infokom:350113 |
Stdio.recursive_rm("testsuite_test_dir.pmod"); |
mkdir("testsuite_test_dir.pmod"); |
Stdio.write_file("testsuite_test_dir.pmod/module.pmod", |
#" |
.A a() {return 0;} |
"); |
Stdio.write_file("testsuite_test_dir.pmod/A.pike", |
#" |
void create (.X x) {.y();} |
"); |
|
// Compilation handler that hides compilation errors. |
class handler |
{ |
void handle_error(array(mixed)|object trace) { } |
void compile_error(string file, int line, string err) { } |
void compile_warning(string file, int line, string err) { } |
}; |
|
object orig_master = master(); |
replace_master(object_program(orig_master)()); |
master()->set_inhibit_compile_errors(handler()); |
mixed err = catch { |
compile_string("import \".\"; " |
"int foo() { testsuite_test_dir.a(); }", |
"test",handler()); |
}; |
master()->set_inhibit_compile_errors(0); |
replace_master(orig_master); |
if(err) |
{ |
Stdio.recursive_rm("testsuite_test_dir.pmod"); |
return 0; |
} |
|
return 1; |
]],0); |
|
test_do([[ |
Stdio.recursive_rm("testsuite_test_dir.pmod"); |
mkdir("testsuite_test_dir.pmod"); |
|
Stdio.write_file("testsuite_test_dir.pmod/module.pmod", |
#" |
.A a(); |
class X {} |
"); |
Stdio.write_file("testsuite_test_dir.pmod/A.pike", |
#" |
.X f() {return 0;} |
"); |
|
object orig_master = master(); |
replace_master(object_program(orig_master)()); |
mixed err = catch { |
compile_string("import \".\"; " |
"int foo() { testsuite_test_dir.A(); }", |
"test"); |
}; |
replace_master(orig_master); |
if (err) throw (err); |
|
Stdio.recursive_rm("testsuite_test_dir.pmod"); |
]]); |
|
test_do([[ |
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
mkdir ("testsuite_test_dir.pmod"); |
|
Stdio.write_file ("testsuite_test_dir.pmod/module.pmod", #"\ |
.B b(); |
class X {}"); |
Stdio.write_file ("testsuite_test_dir.pmod/A.pike", #"\ |
int f() {return 0;}"); |
Stdio.write_file ("testsuite_test_dir.pmod/B.pike", #"\ |
inherit .A; |
.X g() {return f() && .X();}"); |
|
object orig_master = master(); |
replace_master (object_program (orig_master)()); |
mixed err = catch { |
compile_string ("import \".\";\n" |
"int foo() { testsuite_test_dir.B(); }", |
"test"); |
}; |
replace_master (orig_master); |
if (err) throw (err); |
|
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
]]); |
|
test_do([[ |
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
mkdir ("testsuite_test_dir.pmod"); |
|
Stdio.write_file ("testsuite_test_dir.pmod/module.pmod", #"\ |
.B b(); |
class X {}"); |
Stdio.write_file ("testsuite_test_dir.pmod/A.pike", #"\ |
int f() {return 0;}"); |
Stdio.write_file ("testsuite_test_dir.pmod/B.pmod", #"\ |
class B { |
inherit .A; |
.X g() {return f() && .X();} |
}"); |
|
object orig_master = master(); |
replace_master (object_program (orig_master)()); |
mixed err = catch { |
compile_string ("import \".\";\n" |
"int foo() { testsuite_test_dir.B.B(); }", |
"test"); |
}; |
replace_master (orig_master); |
if (err) throw (err); |
|
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
]]); |
|
test_do([[ |
// Problem: The expression .B.c in module.pmod is resolved during |
// compilation pass 1 of B.pike, but it's only declared then and |
// doesn't yet have any value. |
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
mkdir ("testsuite_test_dir.pmod"); |
|
Stdio.write_file ("testsuite_test_dir.pmod/module.pmod", #"\ |
mixed x = .B.c; |
class A {}"); |
Stdio.write_file ("testsuite_test_dir.pmod/B.pike", #"\ |
constant c = .A();"); // Should give a "not constant" compile error. |
|
// Compilation handler that hides compilation errors. |
class handler |
{ |
void handle_error(array(mixed)|object trace) { } |
void compile_error(string file, int line, string err) { } |
void compile_warning(string file, int line, string err) { } |
}; |
|
object orig_master = master(); |
replace_master (object_program (orig_master)()); |
mixed err = catch { |
compile_string (#"\ |
mixed foo() {return .testsuite_test_dir.A;}", |
"test", handler()); |
}; |
replace_master (orig_master); |
if (!err) error ("Expected compile error.\n"); |
if (!objectp (err) || !err->is_compilation_error) throw (err); |
|
Stdio.recursive_rm("testsuite_test_dir.pmod"); |
]]); |
|
test_any_equal([[ |
// Problem: module.pmod is in pass 1 when it tries to resolve the |
// .B.c constant and is therefore temporarily interned as a |
// placeholder object. The (<>) in B.pike is equivalent to |
// aggregate_multiset, which due to the import is looked up in the |
// placeholder object and therefore resolved as a nonconstant |
// placeholder object. |
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
mkdir ("testsuite_test_dir.pmod"); |
|
Stdio.write_file ("testsuite_test_dir.pmod/module.pmod", #"\ |
mixed x = .B.C; |
mixed foo() {return x->c;}"); |
Stdio.write_file ("testsuite_test_dir.pmod/B.pike", #"\ |
import \".\"; |
class C { |
constant c = (<>); |
}"); |
|
object orig_master = master(); |
replace_master (object_program (orig_master)()); |
mixed res; |
mixed err = catch { |
res = compile_string (#"\ |
mixed foo() {return .testsuite_test_dir.foo();}", |
"test")()->foo(); |
}; |
replace_master (orig_master); |
if (err) throw (err); |
Stdio.recursive_rm("testsuite_test_dir.pmod"); |
return res; |
]], (<>)); |
|
cond(0,[[ |
test_do([[ |
// This is a case of cyclic references I think should work, but |
// afaict it's not possible without changing the resolve methods |
// thoroughly. /mast |
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
mkdir ("testsuite_test_dir.pmod"); |
|
Stdio.write_file ("testsuite_test_dir.pmod/A.pmod", #"\ |
.B.B b() {} |
class A {} |
class Ab {int ai() {return 4711;}} |
class Ad {inherit .B.Bb; int ai() {return bi() + 1;}}"); |
Stdio.write_file ("testsuite_test_dir.pmod/B.pmod", #"\ |
.A.A a() {} |
class B {} |
class Bb {int bi() {return 17;}} |
class Bd {inherit .A.Ab; int bi() {return ai() - 1;}}"); |
|
object orig_master = master(); |
replace_master (object_program (orig_master)()); |
mixed err = catch { |
compile_string (#"\ |
import \".\"; |
int foo() { |
testsuite_test_dir.A.Ad(); |
testsuite_test_dir.B.Bd(); |
}", "test"); |
}; |
replace_master (orig_master); |
if (err) throw (err); |
|
Stdio.recursive_rm ("testsuite_test_dir.pmod"); |
]]); |
]]); |
|
test_compile_any([[int log() { return 17; } class Greta { int hanna() { return log(); } }]]) |
test_compile_any([[int kajsa(int a,int b) { return 17; } class Jenny { int kajsa() { return 17; } class Greta { int hanna() { return kajsa(); } } }]]) |
test_any([[add_constant("kajsa",lambda(int a,int b) { return 17; }); return compile_string("int kajsa() { return 17; } class Greta { int hanna() { return kajsa(); } }")()->kajsa()]],17) |
|
test_compile([[Stdio.File foo=Stdio.File();]]) |
test_compile([[ string|multiset(string) foo; |
array(string) gazonk; |
array(string) bar = indices(foo)-gazonk; |
]]) |
test_compile([[class { Stdio.File foo=Stdio.File(); }]]) |
test_compile_any([[void foo(Stdio.FILE f) {}]]) |
test_compile_any([[void foo(array(Stdio.FILE) f) {}]]) |
test_compile_any([[void foo(array(Stdio.FILE) f) {}]]) |
test_compile_any([[Stdio.File foo(array(Stdio.FILE) f) { return f[0]; }]]) |
test_compile_any([[ |
class a { |
int `== (mixed x) { |
return 0; |
} |
} |
|
class b { |
inherit a; |
class c { |
int d (string x, string y) { |
return x==y; |
} |
} |
} |
]]) |
test_compile([[Stdio.File foo=Stdio.FILE();]]) |
|
test_any([[string gurk="bozo"; string b(int x) { return (x?b(x-1)+gurk:""); }; return b(5)]],[["bozo"*5]]) |
|
dnl this should really work... |
dnl test_compile_any([[void foo(int,string,...);]]) |
|
dnl This test doesn't run out of stack anymore, freaky |
dnl test_eval_error([[class X { int create() { create(); } }();]]) |
test_compile_error([[ int float; ]]) |
test_compile_error([[ int array; ]]) |
test_compile_error([[ int function; ]]) |
test_compile_error([[ int int; ]]) |
test_compile_error([[ int mapping; ]]) |
test_compile_error([[ int multiset; ]]) |
test_compile_error([[ int object; ]]) |
test_compile_error([[ int string; ]]) |
test_compile_error([[ int void; ]]) |
test_compile_error([[ int inline; ]]) |
test_compile_error([[ int local; ]]) |
test_compile_error([[ int nomask; ]]) |
test_compile_error([[ int predef; ]]) |
test_compile_error([[ int private; ]]) |
test_compile_error([[ int protected; ]]) |
test_compile_error([[ int public; ]]) |
test_compile_error([[ int static; ]]) |
test_compile_error([[ int final; ]]) |
test_compile_error([[ int do; ]]) |
test_compile_error([[ int else; ]]) |
test_compile_error([[ int return; ]]) |
test_compile_error([[ int constant; ]]) |
test_compile_error([[ int import; ]]) |
test_compile_error([[ int inherit; ]]) |
test_compile_error([[ int catch; ]]) |
test_compile_error([[ float gauge; ]]) |
test_compile_error([[ int lambda; ]]) |
test_compile_error([[ int sscanf; ]]) |
test_compile_error([[ int switch; ]]) |
test_compile_error([[ int typeof; ]]) |
test_compile_error([[ int break; ]]) |
test_compile_error([[ int case; ]]) |
test_compile_error([[ int continue; ]]) |
test_compile_error([[ int default; ]]) |
test_compile_error([[ int for; ]]) |
test_compile_error([[ int foreach; ]]) |
test_compile_error([[ int if; ]]) |
test_compile_error([[ int float = 0; ]]) |
test_eval_error([[ return 0.0[0]; ]]) |
test_eval_error([[ return 0[0]; ]]) |
test_compile_error([[constant x=class {}(); ]]) |
|
test_compile_error_any([[ |
mixed foo; |
mapping query_variables() { return ([]); }; |
mixed foo(mixed bar) { return 1/foo; } |
]]) |
|
test_compile_error_any([[ |
class A {int wrong = "bogus"; void create() {}} |
class B {inherit A;} |
]]) |
|
|
test_compile([[float x=(gauge { return; },1.0);]]) |
cond( [[ master()->resolv("Gmp")->mpz ]], |
[[ |
test_compile_error([[object x = Gmp.mpz(17); constant y = x;]]) |
]]) |
test_any([[object(Stdio.File) f; f=Stdio.File(); return 1]],1) |
test_compile([[float t=gauge { string foo; };]]) |
test_compile_any([[class { object(Stdio.FILE) f; void create() { f=Stdio.FILE(); }}]]) |
test_eq([[compile_string("#define A(X) (X)\nint x() { return A \n\t(1); }")()->x()]],1) |
|
test_any([[class G { mapping t=([]); |
class tO { void init(string name) { t[name]=this_object(); }} |
class W { inherit tO; void create() { init("foo"); }} |
}; object x=G(); x->W(); return objectp(x->t->foo)]],1) |
|
test_program([[class foo { program x() { return class {}; }}; class bar { inherit foo; program x() { return class {}; }} int a() { return foo()->x != bar()->x(); }]]) |
|
test_any([[ |
class A { |
constant gurka = 2; |
int foo = gurka; |
}; |
class B { |
static inherit A; |
constant gurka = 1; |
int bar; |
|
void create() { bar = foo; } |
}; |
return B()->bar; |
]], 1) |
|
test_any([[ |
class A { |
constant gurka = 2; |
int foo = gurka; |
}; |
class B { |
static inherit A; |
constant gurka = 1; |
int bar; |
int baz = 3; |
|
void create() { bar = baz + foo; } |
}; |
return B()->bar; |
]], 4) |
|
test_any([[ |
class A { |
constant gurka = 1; |
int foo = gurka; |
}; |
class B { |
constant banan = 2; |
int foo = banan; |
}; |
class C { |
static inherit A; |
static inherit B; |
constant gurka = 3; |
constant banan = 4; |
int bar; |
int baz = 5; |
|
void create() { bar = baz + A::foo + B::foo; } |
}; |
return C()->bar; |
]], 12) |
|
test_any([[ |
class A { int a = 1; }; |
class B { int b = 2; }; |
class C { |
inherit A; |
inherit B; |
int c = 4; |
}; |
class D { |
inherit C; |
}; |
object d = D(); |
return d->a + d->b + d->c; |
]], 7) |
|
test_compile_error_any([[ |
class AScope |
{ |
int gurka; |
class A |
{ |
int func() { return gurka; } |
} |
} |
|
class CScope |
{ |
string hohum; |
class C |
{ |
inherit AScope.A; |
} |
} |
|
]]) |
|
dnl Come back when we decide that this should be possible |
dnl test_do([[ |
dnl class A { |
dnl constant i = 5; |
dnl }; |
dnl class B { |
dnl inherit A; |
dnl int i = 17; |
dnl }; |
dnl B(); |
dnl ]]) |
|
|
test_any([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit C; }; |
return Program.inherits(D,A); |
]],1) |
|
test_any([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit C; }; |
return Program.inherits(A,D); |
]],0) |
|
test_any([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit C; }; |
return Program.inherits(A,C); |
]],0) |
|
test_any([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit C; }; |
return Program.inherits(C,A); |
]],1) |
|
test_any_equal([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit C; }; |
return Program.inherit_list(D); |
]],[[ ({ C }) ]] ) |
|
test_any_equal([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit A; inherit B; inherit C; }; |
return Program.inherit_list(D); |
]],[[ ({ A,B,C }) ]]) |
|
test_any_equal([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit C; }; |
return Program.inherit_tree(D); |
]],[[ ({D, ({C, ({B, ({A})})})}) ]]) |
|
test_any([[ |
class A {}; |
class B { inherit A; }; |
class C { inherit B; }; |
class D { inherit C; }; |
return sizeof( Program.all_inherits(D) - ({A,B,C}) ); |
]],0) |
|
test_tests([[ |
|
int errors; |
int tests; |
|
#define indent(X) (X) |
#define FMT "%d:%d " |
|
int maxdepth; |
int quiet; |
string status_prefix=""; |
|
class Codec { |
string nameof(mixed x) |
{ |
return ([ trace:"efun:trace", werror:"efun:werror", `+:"efun:`+" ])[x]; |
} |
|
function functionof(string x) |
{ |
return ([ "efun:trace":trace, "efun:werror":werror, "efun:`+":`+ ])[x] || |
0; |
} |
|
mixed encode_object (object o) {} |
void decode_object (object o, mixed d) {} |
} |
|
void low_generate(int depth, |
array(string) code, |
string acc, |
string ans, |
int cnt) |
{ |
mixed tmp; |
if(--depth<0) |
{ |
string res="None"; |
tests++; |
|
if(!(tests & 63)) |
{ |
__signal_watchdog(); |
if(!quiet) |
werror("\r%s" FMT, status_prefix,maxdepth,tests); |
} |
|
string test=code*"\n"+"\n" |
"mixed Q() { return "+acc+"();}\n" |
"int main() { trace(9); werror(\"%O\\n\","+acc+"()); }\n" |
; |
|
mixed tmp; |
mixed err=catch { |
tmp=compile_string(test)(); |
res=tmp->Q(); |
if(res != ans) |
throw("Test failed"); |
tmp = decode_value(encode_value(tmp, Codec()), Codec()); |
res=tmp->Q(); |
if(res != ans) |
throw("Test failed for encode/decode."); |
}; |
mixed x=Program.inherit_list(object_program(tmp)); |
if(err) |
{ |
errors++; |
werror("\nTest failed:\n----------------------------------\n%s\n---------------------------------\nexpected answer: %O\nAnswer received: %O\n",test,ans,res); |
if(!stringp(err) || !has_prefix(err, "Test failed")) |
{ |
string tmp=master()->describe_backtrace(err); |
array s=tmp/"\n"; |
s=s[..20]; |
werror("%s\n",s*"\n"); |
} |
return; |
} |
}else{ |
low_generate(depth, |
code+ |
({sprintf("string F%d(){ return %s()+\"F%d\"; }",cnt,acc,cnt)}), |
sprintf("F%d",cnt), |
sprintf("%sF%d",ans,cnt), |
cnt+1); |
|
for(int e=0;e<sizeof(code);e++) |
{ |
low_generate(depth, |
code[..e-1]+({ |
sprintf("class C%d {\n%s\n};",cnt,indent(code[e..]*"\n")) |
}), |
sprintf("C%d()->%s",cnt,acc), |
ans,cnt+1); |
} |
|
|
if(sscanf(acc,"%s()->%s",string classname,string rest)) |
{ |
low_generate(depth, |
code+({sprintf("inherit %s;",classname) }), |
rest, |
ans, |
cnt); |
} |
} |
} |
|
array(int) a() |
{ |
werror("\nTesting vtables and scope access.\n"); |
|
quiet = !_verbose; |
|
int total_tests; |
for(maxdepth=1;maxdepth<9 && !errors;maxdepth++) |
{ |
low_generate(maxdepth, |
({ "string X(){return \"X\";}" }), |
"X", |
"X",0); |
|
status_prefix+=sprintf(FMT,maxdepth,tests); |
if(quiet) |
werror("%d .. ",maxdepth); |
else |
werror("\r%s",status_prefix); |
total_tests+=tests; |
tests=0; |
} |
|
werror("\n"); |
return ({ total_tests-errors, errors }); |
} |
|
]]) |
|
|
|
|
test_true([[Program.implements( class { int x; string y; void foo(int x) {} }, |
class { void foo(mixed z) {} int x; })]]) |
test_false([[Program.implements( class { int x; string y; void foo(int x) {} }, |
class { void foo(mixed z) {} string x; })]]) |
|
test_eq([[object_program(master())]],[[(program)"/master"]]) |
test_compile([[object("master") m = master();]]) |
test_any([[if(int x=1,y=2) return x;]],1) |
test_any([[int x; x++; if(x) return x; return -1;]],1) |
test_any([[int x; if(x) return x; return -1;]],-1) |
test_any([[int x,y; if(x==y || x==1) return 2; return 0;]],2); |
test_any([[int x,y; if(x==y && x==0) return 2; return 0;]],2); |
test_any([[int x,y=1; if(x==y || x==1) return 2; return 0;]],0); |
test_any([[int x,y=1; if(x==y && x==0) return 2; return 0;]],0); |
|
test_eq([[ "\007" & "\023"]],"\003") |
test_eq([[ "\007" | "\023"]],"\027") |
test_eq([[ "\007" ^ "\023"]],"\024") |
|
|
test_any([[ |
return class { int i=17; }()["i"] |
]],17) |
|
test_any([[ |
return class { int i=17; mixed `[](string foo) { return i; }}()[""] |
]],17) |
|
test_any([[ |
return class { int i=17; mixed `[](string foo) { return ::`[]("i"); }}()[""] |
]],17) |
|
test_any([[ |
return class { int i=17; mixed `[](string foo) { return ::`[]; }}()[""]("i") |
]],17) |
|
test_any([[ |
return class { int i=17; mixed `[](string foo) { return ::`[]; }}()[""]("y") |
]],0) |
|
test_any([[ |
object o=class { |
int i=17; |
mixed `[](string foo) { return ::`[]=; } |
mixed `[]=(string ind, mixed foo) {} |
}(); |
|
o[""]("i",99); |
return o->i; |
]],99) |
|
test_any([[ |
object o=class { |
int foo=7; |
int bar=11; |
int i=17; |
int gazonk=12; |
mixed `[](string foo) { return ::`[]=; } |
mixed `[]=(string ind, mixed foo) {} |
}(); |
|
o[""]("i",99); |
return o->i; |
]],99) |
|
test_any([[ |
class Fonk { |
int foo=1; |
int bar=2; |
int i=17; |
int gazonk=3; |
}; |
|
object o=class |
{ |
inherit Fonk; |
mixed `[](string foo) { return ::`[]=; } |
mixed `[]=(string ind, mixed foo) {} |
}(); |
|
o[""]("i",99); |
return o->i; |
]],99) |
|
test_any([[ |
class Fonk { |
int foo=1; |
int bar=2; |
int i=17; |
int gazonk=3; |
}; |
|
object o=class |
{ |
inherit Fonk : zonk; |
mixed `[](string foo) { return zonk::`[]=; } |
mixed `[]=(string ind, mixed foo) {} |
}(); |
|
o[""]("i",99); |
return o->i; |
]],99) |
|
test_any([[ |
class A {int foo() {return bar();} int bar();}; |
class B {int bar() {return 1;}}; |
class C {inherit A; inherit B; int bar() {return B::bar();}}; |
return C()->foo(); |
]], 1) |
|
test_compile_any([[ |
class X { void hej() {} } |
class Y { inherit X:banan; void hopp() { banan::hej(); } } |
]]) |
|
|
test_compile_any([[ |
class X { static void hej() {} } |
class Y { inherit X:banan; void hopp() { ::hej(); } } |
]]) |
|
test_compile_any([[ |
class X { static void hej() {} } |
class Y { inherit X; void hopp() { X::hej(); } } |
]]) |
|
test_compile_any([[ |
class X { static void hej() {} } |
class Y { public inherit X:banan; void hopp() { banan::hej(); } } |
]]) |
|
test_compile_any([[ |
class X { static void hej() {} } |
class Y { inherit X:banan; void hopp() { banan::hej(); } } |
]]) |
|
// Testing hidden identifier lookup with :: |
|
test_program([[ |
class X { |
int i = 17; |
class Y { |
constant i = 18; |
mixed f (int i) {return ({i, Y::i, X::i});} |
} |
} |
int a() {return equal (X()->Y()->f (19), ({19, 18, 17}));} |
]]) |
|
test_compile_error_any([[ |
#pike 7.2 |
class X { |
int i = 17; |
class Y { |
constant i = 18; |
mixed f (int i) {return ({i, Y::i, X::i});} |
} |
} |
]]) |
|
test_compile_error_any([[ |
class X { |
constant i = 18; |
mixed f() {return Y::i;} |
} |
]]) |
|
test_program([[ |
class A { |
int i = 17; |
} |
class X { |
inherit A: Y; |
class Y { |
constant i = 18; |
mixed f() {return Y::i;} |
} |
} |
int a() {return X()->Y()->f() == 18;} |
]]) |
|
test_program([[ |
#pike 7.2 |
class A { |
int i = 17; |
} |
class X { |
inherit A: Y; |
class Y { |
constant i = 18; |
mixed f() {return Y::i;} |
} |
} |
int a() {return X()->Y()->f() == 17;} |
]]) |
|
test_program([[ |
class A { |
string s = "A"; |
} |
class B { |
constant s = "B"; |
} |
class X { |
constant s = "X"; |
inherit A; |
class Y { |
inherit B: A; |
constant s = "Y"; |
mixed f() {return X::s + X::A::s + Y::s + Y::A::s + A::s;} |
} |
} |
int a() {return X()->Y()->f() == "XAYBB";} |
]]) |
|
test_program([[ |
class A { |
string s = "A"; |
} |
inherit A; |
class X { |
constant s = "X"; |
mixed f (string s) {return s + X::s + A::s;} |
} |
int a() {return X()->f("L") == "LXA";} |
]]) |
|
test_program([[ |
class A { |
string f() {return "A";} |
string g() {return A::f();} |
} |
class B { |
inherit A; |
string f() {return "B";} |
} |
int a() {return B()->g() == "B";} |
]]) |
|
test_program([[ |
class A { |
string g() {return A::f();} |
string f() {return "A";} |
} |
class B { |
inherit A; |
string f() {return "B";} |
} |
int a() {return B()->g() == "B";} |
]]) |
|
test_program([[ |
class A { |
string f() {return "A";} |
string g() {return A::f();} |
} |
class B { |
string f() {return "B";} |
inherit A; |
} |
int a() {return B()->g() == "B";} |
]]) |
|
test_program([[ |
class A { |
string f() {return "A";} |
class I { |
string g() {return A::f();} |
} |
} |
class B { |
inherit A; |
string f() {return "B";} |
} |
int a() {return B()->I()->g() == "B";} |
]]) |
|
// Testing 'global::' |
|
test_equal([[ |
compile_string (#" |
string p = \"g\"; |
mixed f (string p) {return ({global::p, p});}")()->f ("l"); |
]], ({"g", "l"})) |
|
test_eval_error([[ |
compile_string (#" |
string pp = \"g\"; |
mixed f (string p) {return global::p;}"); |
]]) |
|
test_eval_error([[ |
compile_string (#" |
#pike 7.2 |
string p = \"g\"; |
mixed f (string p) {return global::p;}"); |
]]) |
|
test_equal([[ |
compile_string (#" |
int x = 23; |
class A { |
constant x = 24; |
} |
inherit A; |
class X { |
int x = 32; |
mixed f (int x) {return ({global::x, global::A::x, X::x, x});} |
}")()->X()->f (33); |
]], ({23, 24, 32, 33})) |
|
// Testing 'global.' |
|
test_compile([[ |
mixed a() {return global.Parser.HTML;} |
]], 0); |
|
test_compile_error([[ |
#pike 7.2 |
mixed a() {return global.Parser.HTML;} |
]], 0); |
|
test_any([[ |
if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n"); |
return compile_string (#" |
class Parser {constant HTML = 1;} |
mixed foo() {return programp (Parser.HTML);}")()->foo(); |
]], 0); |
|
test_any([[ |
if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n"); |
return compile_string (#" |
mixed foo() {return programp (Parser.HTML);} |
class Parser {constant HTML = 1;}")()->foo(); |
]], 0); |
|
test_any([[ |
if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n"); |
return compile_string (#" |
class Parser {constant HTML = 1;} |
mixed foo() {return programp (global.Parser.HTML);}")()->foo(); |
]], 1); |
|
test_any([[ |
if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n"); |
return compile_string (#" |
mixed foo() {return programp (global.Parser.HTML);} |
class Parser {constant HTML = 1;}")()->foo(); |
]], 1); |
|
// testing virtual overloading |
test_any([[ |
class fnord |
{ |
int ber() { return 1; } |
int goo() { return ber(); } |
}; |
|
class blorg |
{ |
inherit fnord; |
int ber() { return 2; } |
}; |
return blorg()->goo(); |
]],2) |
|
// testing 'local' |
test_any([[ |
class fnord |
{ |
local int ber() { return 1; } |
int goo() { return ber(); } |
}; |
|
class blorg |
{ |
inherit fnord; |
int ber() { return 2; } |
}; |
return blorg()->goo(); |
]],1) |
|
// testing 'local::' |
test_any([[ |
class fnord |
{ |
int ber() { return 1; } |
int goo() { return local::ber(); } |
}; |
|
class blorg |
{ |
inherit fnord; |
int ber() { return 2; } |
}; |
return blorg()->goo(); |
]],1) |
test_any([[ |
class fnord |
{ |
int ber() { return 1; } |
int goo() { return local::ber()+ber(); } |
}; |
|
class blorg |
{ |
inherit fnord; |
int ber() { return 2; } |
}; |
return blorg()->goo(); |
]],3) |
test_any([[ |
class fnord |
{ |
int ber() { return 1; } |
int goo() { return ber()+local::ber(); } |
}; |
|
class blorg |
{ |
inherit fnord; |
int ber() { return 2; } |
}; |
return blorg()->goo(); |
]],3) |
|
test_compile_error_any([[class X {int x; int f() {return local::x;}}]]) |
test_compile_any([[ |
#pike 7.2 |
class X {int x; int f() {return local::x;}} |
]]) |
|
// Testing the 'inline' keyword |
test_program([[class foo { inline int c() { return time(); } int d() { return c(); } }; class bar { inherit foo; int c() { return 0; } } int a() { return bar()->d(); }]],0) |
|
test_compile_any([[ |
class top |
{ |
class the_class |
{ |
} |
} |
|
class inherit_top |
{ |
inherit top:top; |
|
constant top_the_class=top::the_class; |
|
class the_other_class |
{ |
inherit top_the_class; |
} |
} |
]]) |
|
// Testing __INIT |
test_any([[ |
class X { int x = 1; }; |
class Y { int y = 2; }; |
class Z { inherit X; inherit Y; int z = 4; }; |
object zz = Z(); |
return zz->x + zz->y + zz->z; |
]], 7) |
|
test_do([[ |
// bug 3006 |
class X { |
constant foo = Foo; |
class Foo {} |
void bar() |
{ |
foo f = Foo(); |
} |
}; |
]]) |
|
test_program([[ |
// Another variant of [bug 3006]. |
class X { |
constant foo = Foo; |
class Foo {} |
} |
int a() {return programp (X.foo);} |
]]) |
|
cond(0,[[ |
test_program([[ |
// This shows a case when on-demand resolving is required. |
class X { |
constant foo = a + 1; |
constant a = b + 1; |
constant b = c + 1; |
constant c = d + 1; |
constant d = 1; |
}; |
int a() {return X.foo == 5;} |
]]) |
test_program([[ |
// Reference case for the test above. |
class X { |
constant d = 1; |
constant c = d + 1; |
constant b = c + 1; |
constant a = b + 1; |
constant foo = a + 1; |
}; |
int a() {return X.foo == 5;} |
]]) |
]]) |
|
test_any([[ |
class X { |
static string f() { return "p"; } |
static class gazonk { void create() { f(); }}; |
static class g { object e() { return gazonk(); }}; |
void create() { g()->e(); }}; return objectp(X()); ]],1) |
test_any([[class A { protected int x=1; }; class B { inherit A; int foo() { return A::x; }}; return A()->x==B()->x && B()->foo()==A()->x;]],1) |
test_any([[class C { int q() { return p(); } int p() { return 17; }}; return C()->q();]],17) |
test_any([[class C1 { |
class D { string id() { return "foo"; } }; |
class Y { program YinD() { return D; }} }; |
class C2 { inherit C1; class D { string id() { return "bar"; } } }; |
return C2()->Y()->YinD()()->id()]],"bar") |
test_any([[object o=class foo{int c;class bar{void create(){c++;};}}(); o->bar(); return o->c;]],1) |
test_do([[add_constant("GURKA2",class foo { int c; class bar{void create() {c+=17;}}}()); ]]) |
test_any([[class x { inherit GURKA2.bar; }(); return GURKA2->c;]],17) |
test_any([[class x { inherit GURKA2.bar; }(); return GURKA2->c;]],34) |
|
test_do([[add_constant("GURKA2",class foo { int c; class bar{void create() { class sune { void create() {c+=17;}}(); }}}()); ]]) |
test_any([[class x { inherit GURKA2.bar; }(); return GURKA2->c;]],17) |
test_any([[class x { inherit GURKA2.bar; }(); return GURKA2->c;]],34) |
test_do([[add_constant("GURKA2");]]); |
|
test_eq(class { static int foo=17; }()->foo,0) |
test_eval_error(class c { static int foo=17; }()->foo=18;) |
test_equal( [[ ({ (["foo":"bar"]), (<"foo">), ([]) })->foo ]], [[ ({"bar",1,0}) ]]) |
test_any([[mixed a=({([]),0}); a[1]=a; return a->foo[0];]],0) |
test_eval_error([[return column(({0}),"foo");]]) |
|
test_any([[ |
class A { constant a=0; int foo() { return a; } }; |
class B { inherit A; constant a=1; }; |
return B()->foo(); ]], 1) |
|
test_any([[ |
class p1 { int foo() { return 1; }}; |
class p2 { int foo() { return 3; }}; |
class c1 { inherit p1; inherit p2; int foo() { return p1::foo()+p2::foo(); }}; |
class c2 { inherit c1; }; return c2()->foo();]],4) |
|
test_any([[ |
class p1 { int foo() { return 1; } }; |
class p2 { int foo() { return 2; } }; |
class c1 { inherit p1; inherit p2; }; |
return c1()->foo();]],2) |
|
test_any([[class foo { int x=random(100); int `<(object o) { return x < o->x; } }; array(object) o=allocate(100,foo)(); sort(o); for(int e=1;e<100;e++) if(o[e-1]->x > o[e]->x) return e; return -1;]],-1) |
|
test_any([[ |
mixed ret=({}); |
int a, b = 3; |
for (a = 0; a < b; a++) { |
ret+=({a,b}); |
if (a % 2) b += 1; |
} |
return equal(ret,({0,3,1,3,2,4,3,4,4,5})); |
]],1) |
|
test_any([[ |
mixed ret=({}); |
int a, b = 3; |
for (a = 0; a < b; a++) { |
ret+=({a,b}); |
if (a % 2) b ++; |
} |
return equal(ret,({0,3,1,3,2,4,3,4,4,5})); |
]],1) |
|
test_any([[ |
mixed ret=({}); |
int a, b = 3; |
for (a = 0; a < b; a++) { |
ret+=({a,b}); |
if (a % 2) b=b+1; |
} |
return equal(ret,({0,3,1,3,2,4,3,4,4,5})); |
]],1) |
|
test_any([[ |
mixed ret=({}); |
int a, b = 3; |
for (a = 0; a < b; a++) { |
ret+=({a,b}); |
if (a % 2) b-=-1; |
} |
return equal(ret,({0,3,1,3,2,4,3,4,4,5})); |
]],1) |
|
|
test_compile_error([[void foo() { 1++; }]]) |
dnl test_compile_error([[void foo() { return destruct(this_object()); }]]) |
test_any([[class foo { constant x=17; }; class bar { inherit foo; constant x=18; }; return bar()->x;]],18) |
test_program([[inline string foo(string s){ while(s[0] == ' ' || s[0] == '\t') s = s[1..]; return(s); } string a() { return foo(" bar"); }]]) |
|
|
// lambda function tests |
|
test_true([[lambda(int x) { return lambda() { return x; };}]]) |
test_eq([[lambda(int x) { return lambda() { return x; };}(4)()]],4) |
test_eq([[lambda(int x) { return lambda() { return x; };}(17)()]],17) |
test_eq([[lambda(int x) { return lambda() { return lambda() { return x; };};}(17)()()]],17) |
|
// local function tests |
test_eq(120, |
[[ lambda() |
{ |
int f(int i) { return i == 0 ? 1 : i*f(i-1); }; |
return f(5); |
}(); ]]) |
|
test_eq([[function f; |
for(int i = 0; i < 2; i++) |
{ {int _i = i; f = lambda(int j) { return _i+j; }; } } |
return f(17);]], |
[[function f; |
for(int i = 0; i < 2; i++) |
{ {int _i = i; f = lambda(int j) { return _i+j; }; } int FEL; } |
return f(17);]]); |
|
test_any([[ |
int x,y,z; |
function p; |
void foo() { y+=7; }; |
void bar() |
{ |
foo(); |
void gazonk() |
{ |
foo(); |
void quux() |
{ |
foo(); |
y+=4711; |
}; |
p=quux; |
}; |
|
gazonk(); |
gazonk(); |
}; |
foo(); |
bar(); |
p(); |
return y; |
]], 7 * 5 + 4711 ) |
|
test_any([[ |
int x=1; |
void for10(function f) { for(int e=0;e<10;e++) f(); }; |
for10(lambda() { x++; }); |
return x; |
]], 11) |
|
// implicit lambda tests |
test_any([[ |
int x=1; |
void for10(function f) { for(int e=0;e<10;e++) f(); }; |
for10() { x++; }; |
return x; |
]], 11) |
|
test_compile_error([[ |
int x=1; |
void for10(function f) { for(int e=0;e<10;e++) f(); }; |
for10() { x++; } |
return x; |
]]) |
|
test_any([[ |
int x; |
for(int i=5; i < 10; i++) x++; |
return x; |
]], 5) |
|
test_true([[lambda(function f) {return 1;}(object_program(this_object()));]]) |
test_any([[ |
function my_lambda; |
|
{ |
string foo = "foo", bar = "bar"; |
my_lambda = lambda() { return foo; }; |
} |
|
int really_magic_var; |
return my_lambda(); |
]],"foo") |
|
test_eq([[class c { int `()(){ return 4711; } }()(); ]],4711) |
teste_eval_error(mixed foo=({}); sort(@foo); ) |
test_compile_error([[int foo() { return 1} ; constant foo=(["foo":foo]); return foo->foo();]]) |
test_compile_error([[class T{void p(object e,object f){lambda::create(f);}}]]) |
test_eval_error(array foo=({}); return mkmapping(foo,({1})); ) |
test_compile_error([[mapping (string:array(string:string)) foo=([]); ]]) |
test_compile_error([[int a() { switch(random(2)) { case 3: if(random(2)) { case 0: return 1; } else { case 1: return 2; } } }]]) |
|
test_true(encode_value(0)) |
test_true(encode_value(0)[0]=='\266') |
define(test_encode, [[ test_equal($1, decode_value(encode_value($1))) |
test_equal($1, decode_value(encode_value_canonic($1))) ]]) |
test_eq(replace("foobar","","X"),"fXoXoXbXaXr") |
test_encode(0) |
test_encode("") |
test_encode(0.0) |
test_encode(1.0) |
test_encode(-1.0) |
test_encode(12.0) |
test_encode(100000.0) |
test_encode(3.1875) |
test_encode(0.0000019073486328125) |
test_encode(({})) |
test_encode(([])) |
test_encode("foobar") |
test_encode((<>)) |
test_encode("\7") |
test_encode("\77") |
test_encode("\777") |
test_encode("\7777") |
test_encode("\77777") |
test_encode("\777777") |
test_encode("\7777777") |
test_encode("\77777777") |
test_encode(({"en","sv","de"})) |
test_encode((<"en","sv","de">)) |
test_encode((["en":1,"sv":2,"de":3])) |
test_encode(({"s",1,0,-3.40625})) |
test_encode((<"s",1,0,-3.40625>)) |
test_encode((["s":1,1:2,0:3,-3.40625:4])) |
test_encode((<1, 2, 2, 3, 3, 3>)) |
test_eq(decode_value("\210\201"),1) |
test_eq(decode_value("\210\011\001"),-1) |
test_eq(decode_value("\206\200"),"")) |
test_equal(decode_value("\200\200"),({})) |
test_equal(decode_value("\206\206\146\157\157\142\141\162"),"foobar") |
test_any([[mixed a=({0}); a[0]=a; return equal(a, decode_value(encode_value(a)));]], 1) |
test_any([[ int e; for(e=0;e<100000;e+=1+(e>>4)) if(decode_value(encode_value(e))!=e) return e; return -1;]], -1) |
test_any([[ int e; for(e=0;e<100000;e+=1+(e>>4)) if(decode_value(encode_value(-e))!=-e) return e; return -1;]], -1) |
|
test_eval_error([[return decode_value("\266ke0\241\346abc\b&\346de~\200\335\1\362PO\35\242")]]) |
test_eval_error([[return decode_value("\266ke0\241\346abcpf\221\337v\37\224")]]) |
test_eval_error([[return decode_value("\266ke0\241\346abc\b&\346def`\266\212\340\337\b\252\b")]]) |
test_eval_error([[return decode_value("\266ke0\241\346abc\b&\346def`\266\264\22\330\207")]]) |
test_eval_error([[return decode_value("\266ke0\241\262\266\216\213{@\333|")]]) |
test_eval_error([[return decode_value("\266ke0\241\346a\211[\266SN\313\331")]]) |
test_eval_error([[return decode_value("\266ke0\241\346ab-\266""6\227}u\320\274\251\211")]]) |
test_eval_error([[return decode_value("\266ke0\241\346abc\b&\346de\276\266\364\30\251s\233UF\362")]]) |
test_eval_error([[return decode_value("\266ke0\241\346abcv\22C\246\264\264L" )]]) |
test_eval_error([[return decode_value("\266ke0\241\260\303\rl")]]) |
|
test_equal(encode_value_canonic ((["en":1,"sv":2,"de":3])), |
encode_value_canonic ((["en":1,"de":3,"sv":2]))) |
test_equal(encode_value_canonic ((["en":1,"sv":2,"de":3])), |
encode_value_canonic ((["de":3,"sv":2,"en":1]))) |
test_equal(encode_value_canonic ((["en":1,"sv":2,"de":3])), |
encode_value_canonic ((["sv":2,"en":1,"de":3]))) |
test_equal(encode_value_canonic ((<"en","sv","de">)), |
encode_value_canonic ((<"en","de","sv">))) |
test_equal(encode_value_canonic ((<"en","sv","de">)), |
encode_value_canonic ((<"de","sv","en">))) |
test_equal(encode_value_canonic ((<"en","sv","de">)), |
encode_value_canonic ((<"sv","en","de">))) |
|
|
test_any([[ |
// bug 3013 |
class Test |
{ |
class Resolver (array c) |
{ |
mixed resolv (string id) |
{ |
if (id == "c") return c; |
} |
} |
|
class Codec |
{ |
mixed fooof (string name) {return all_constants()[name];} |
function objectof = fooof; |
function functionof = fooof; |
function programof = fooof; |
|
string nameof (mixed what) |
{ |
if (string name = search (all_constants(), what)) return name; |
return ([])[0]; |
} |
|
mixed encode_object (object o) {} |
void decode_object (object o, mixed d) {} |
} |
|
mixed main() |
{ |
array c = ({"subres"}); |
object o = compile ( |
#"string res() {return `+(@c());} |
string subres() {return \"foo\";}", |
Resolver (c))(); |
for (int i = 0; i < sizeof (c); i++) |
if (stringp (c[i])) c[i] = o[c[i] ]; |
#ifdef DEBUG |
#define D ,1 |
#else |
#define D |
#endif |
function e=encode_value; |
function d=decode_value; |
return d (e (o, Codec() D), Codec() D)->res(); |
} |
}; |
return Test()->main(); |
]],"foo") |
|
test_any([[ |
// bug 3014 |
class Test |
{ |
class Codec |
{ |
mixed nameof (mixed what) |
{ |
return ([])[0]; |
} |
mixed encode_object (object o) {} |
void decode_object (object o, mixed d) {} |
} |
|
int main() |
{ |
object o = compile_string (#" |
constant x = ({0}); |
int f() {return 17;} |
int g() {return x[0]();} |
")(); |
o->x[0] = o->f; |
function e=encode_value; |
function d=decode_value; |
o = d (e (o, Codec()), Codec()); |
return function_object (o->x[0]) == o; |
} |
}; |
return Test()->main(); |
]],1); |
|
|
test_any([[mixed s="foo"; return s++;]],"foo") |
test_any([[mixed s="foo"; s++; return s;]],"foo1") |
test_any([[mixed s="foo"; return ++s;]],"foo1") |
test_any([[float p=2.0; return p--;]],2.0); |
test_any([[float p=2.0; p--; return p;]],1.0) |
test_any([[float p=2.0; return --p;]],1.0) |
|
test_compile_error(int foo() { LJjjjjJJJ ; }) |
test_true(clone(class c { constant i=1; })->i) |
test_true(clone(class c { constant i=0; mixed `->(string s) { if(s=="i") return 1; }})->i) |
test_true(clone(class c { constant i=1; mixed `->(string s) { return 0; }})["i"]) |
test_true(clone(class c { constant i=0; mixed `[](string s) { if(s=="i") return 1; }})["i"]) |
test_true(clone(class c { optional constant i=0; mixed `[](string s) { if(s=="i") return 1; }})["i"]) |
test_true(clone(class c { mixed `[]=(mixed a, mixed b) { if(a!=b) throw(1); }})[1]=1) |
test_true(clone(class c { mixed `->=(mixed a, mixed b) { if(a!=b) throw(1); }})->i="i") |
|
test_eq((["static":42])->static,42) |
|
test_compile_any(class A {}; class B { inherit A; }) |
|
|
// Automap tests |
|
test_equal([[ ({10,20})[*] + 30 ]], [[ ({40, 50}) ]]) |
test_equal([[ 30 + ({10,20})[*] ]], [[ ({40, 50}) ]]) |
test_equal([[ ({1,2})[*] + ({10,20})[*] ]], [[ ({11, 22}) ]]) |
|
|
test_equal([[ ({ ({10,20}), ({30,40}) })[*][*] + 5 ]], |
[[ ({ ({15,25}), ({35,45}) }) ]]) |
|
test_equal([[ 5 + ({ ({10,20}), ({30,40}) })[*][*] ]], |
[[ ({ ({15,25}), ({35,45}) }) ]]) |
|
test_any_equal([[ |
array a=({ ({10,20}), ({30,40}) }); |
a[*][*] += 5; |
return a; |
]], |
[[ ({ ({15,25}), ({35,45}) }) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
a[*] += -2; |
return a; |
]], [[ ({-1,0,1}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
a[*] += -1; |
return a; |
]], [[ ({0,1,2}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
a[*] += 0; |
return a; |
]], [[ ({1,2,3}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
a[*] += 1; |
return a; |
]], [[ ({2,3,4}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
a[*] += 2; |
return a; |
]], [[ ({3,4,5}) ]]) |
|
|
test_any_equal([[ |
mixed a=({1,2,3}); |
return a[*] += -2; |
]], [[ ({-1,0,1}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
return a[*] += -1; |
]], [[ ({0,1,2}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
return a[*] += 0; |
]], [[ ({1,2,3}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
return a[*] += 1; |
]], [[ ({2,3,4}) ]]) |
|
test_any_equal([[ |
mixed a=({1,2,3}); |
return a[*] += 2; |
]], [[ ({3,4,5}) ]]) |
|
test_equal([[ "foo"[ ({ 2,0,1,2 })[*] ] ]], |
[[ ({ 'o', 'f', 'o', 'o' }) ]]) |
|
test_equal([[ ({ ({1}), ({2}), ({3}) })[*][0] ]], |
[[ ({ 1,2,3 }) ]]) |
|
test_equal([[ ({ ({1,2}), ({3,4}), ({5,6}) })[*][ ({0,1,1})[*] ] ]], |
[[ ({ 1,4,6 }) ]]) |
|
// map tests |
test_any_equal(array a = ({({1,0,0}),({1,1,0}),({0,1,1})}); return map(a,`[],1);, |
({0,1,1})) |
test_any_equal(array a = ({({1,0,0}),({1,1,0}),({0,1,1})}); map(a,`[]=,1,0); return a;, |
({({1,0,0}),({1,0,0}),({0,0,1})})) |
test_any_equal(array a = ({(<1>),(<1,2>),(<2,3>),(<1,3>)}); return map(a,`[],1);, |
({1,1,0,1})) |
test_any_equal(array a = ({(<1>),(<1,2>),(<2,3>),(<1,3>)}); map(a,`[]=,1,0); return a;, |
({(<>),(<2>),(<2,3>),(<3>)})) |
test_any_equal(array a = ({(<"a">),(<"b">),(<>)}); map(a,`->=,"a",1); return a;, |
({(<"a">),(<"a","b">),(<"a">)})) |
test_any_equal(array a = ({([1:10]),([1:11,2:12]),([2:13])}); return map(a,`[],1);, |
({10,11,0})) |
test_any_equal(array a = ({([1:10]),([1:11,2:12]),([2:13])}); map(a,`[]=,1,1); return a;, |
({([1:1]),([1:1,2:12]),([1:1,2:13])})) |
test_any_equal(array a = ({(["a":10]),(["b":11]),([])}); map(a,`->=,"a",1); return a;, |
({(["a":1]),(["a":1,"b":11]),(["a":1])})) |
test_any_equal(array a = ({(["i":1]),([])}); return a["i"];, |
({1,0})) |
test_any_equal(array a = ({(["i":1]),([])}); a["i"] = 7; return a;, |
({(["i":7]),(["i":7])})) |
test_any([[ |
class A {local int i = 10; int ii(){return i;}}; |
class B {inherit A;}; |
class C {inherit A; int i = 11;}; |
array a = ({A(),B(),C()}); |
map(a,`[]=,"i",7); |
return equal(a->i,({7,7,7})) && equal(a->ii(),({7,7,10})); |
]],1) |
test_any([[ |
class A {local int i = 10; int ii(){return i;}}; |
class B {inherit A;}; |
class C {inherit A; int i = 11;}; |
array a = ({A(),B(),C()}); |
a->i = 7; |
return equal(a->i,({7,7,7})) && equal(a->ii(),({7,7,10})); |
]],1) |
test_any([[ |
class A {local int i = 10; int ii(){return i;}}; |
class B {inherit A;}; |
class C {inherit A; int i = 11;}; |
array a = ({A(),B(),C()}); |
map(a,`->=,"i",7); |
return equal(a->i,({7,7,7})) && equal(a->ii(),({7,7,10})); |
]],1) |
test_any_equal([[ |
array a = ({({(["a":"b"]),([]),(["c":17])}),({(["a":"b"]),(["a":7])}),(["b":"d"])}); |
a->a = 1; |
return a; |
]], ({({(["a":1]),(["a":1]),(["a":1,"c":17])}), |
({(["a":1]),(["a":1])}), |
(["a":1,"b":"d"])})) |
test_any_equal([[ |
array a = ({({(["a":"b"]),([]),(["c":17])}),({(["a":"b"]),(["a":7])}),(["b":"d"])}); |
map(a,`->=,"a",1); |
return a; |
]], ({({(["a":1]),(["a":1]),(["a":1,"c":17])}), |
({(["a":1]),(["a":1])}), |
(["a":1,"b":"d"])})) |
|
test_any_equal([[ |
/* This test tests a wild program pointer in the object o. The bug can trig |
a coredump in a later test. */ |
class A { |
array a = ({1}); |
void `->= (string var, mixed val) {::`->= (var, val);} |
}; |
class B { |
inherit A; |
void `->= (string var, mixed val) {if (var) ::`->= (var, val);} |
}; |
object o = B(); |
o->a += ({2}); |
return o->a; |
]], ({1,2})) |
|
test_any_equal([[ |
class A { |
array a = ({1}); |
void `->= (string var, mixed val) {::`->= (var, val);} |
}; |
class B { |
inherit A; |
}; |
object o = B(); |
o->a += ({2}); |
return o->a; |
]], ({1,2})) |
|
test_any_equal([[ |
class A { |
array a = ({1}); |
// void `->= (string var, mixed val) {::`->= (var, val);} |
}; |
class B { |
int z; |
inherit A; |
void `->= (string var, mixed val) { A::`->= (var, val);} |
}; |
object o = B(); |
o->a += ({2}); |
return o->a; |
]], ({1,2})) |
|
test_any_equal([[ |
class FOO |
{ |
int q,w,z; |
}; |
class A { |
array a = ({1}); |
}; |
class B { |
inherit FOO; |
int b,c,d,e,f,g; |
inherit A; |
void `->= (string var, mixed val) { A::`->= (var, val);} |
|