test_true([["$Id: testsuite.in,v 1.500 2002/04/28 02:27:31 mast Exp $"]]); |
|
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([[ |
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;};]]); |
|
// |
|
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;} |
]]) |
|
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; |
} |
]]) |
|
dnl ---------------------------------------------------------------- |
dnl scopes and stuff |
dnl ---------------------------------------------------------------- |
|
dnl |
dnl Undocumented but important behaviour... |
dnl |
test_eq([[Stdio._stdin]],[[Stdio.stdin->_fd]]) |
|
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_program([[ |
|
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; |
} |
} |
|
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); |
} |
} |
} |
|
int a() |
{ |
werror("\nTesting vtables and scope access.\n"); |
|
string testargs=getenv()->TESTARGS; |
if(testargs && |
(has_value(testargs/" ", "-q") || |
has_value(testargs/" ", "-quiet") ) ) |
quiet=1; |
|
switch(getenv("TERM")) |
{ |
case "dumb": |
case "emacs": |
quiet=1; |
werror("Max depth: "); |
} |
|
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"); |
if(errors) werror("%d/%d tests failed.\n",errors,total_tests); |
return !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 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) |
|
// 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_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; } }; 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_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(mixed *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 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]; |
} |
} |
|
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);} |
}; |
object o = B(); |
o->a += ({2}); |
return o->a; |
]], ({1,2})) |
|
|
test_any_equal([[ |
class A { |
array a = ({1}); |
}; |
class B { |
int z; |
inherit A : FNORD; |
|
class Q |
{ |
mixed `-> (string var) |
{ |
return FNORD::`-> (var); |
} |
void `->= (string var, mixed val) |
{ |
FNORD::`->= (var, val); |
} |
} |
}; |
object o = B(); |
object o2=o->Q(); |
o2->a += ({2}); |
return o->a; |
]], ({1,2})) |
|
|
dnl // Undefined behaviour, don't do this - Hubbe |
dnl test_any_equal([[ |
dnl class A { |
dnl array a = ({1}); |
dnl void `->= (string var, mixed val) {::`->= (var, val); a += ({17});} |
dnl }; |
dnl class B { |
dnl inherit A; |
dnl }; |
dnl object o = B(); |
dnl o->a += ({2}); |
dnl return o->a; |
dnl ]], ({1,2,17})) |
|
cond(0,[[ |
dnl This test is not really right, since ::`->= is defined to look up |
dnl statically. Still, a variant of ::`->= that does a low-level dynamic |
dnl lookup instead would be really useful in cases like this. |
test_any_equal([[ |
class A { |
int f; |
void `->= (string var, mixed val) {::`->= (var, val); f = 17;} |
}; |
class B { |
inherit A; |
array a = ({1}); |
}; |
object o = B(); |
o->a += ({2}); |
return o->a + ({o->f}); |
]], ({1,2,17})) |
]]) |
|
test_true(mappingp(_memory_usage())) |
test_true(_refs("")); |
test_true(_refs(({}))); |
test_true(_refs(([]))); |
test_true(_refs(this_object())) |
test_true(arrayp( _next(({})) || _prev(({})))) |
test_do(object o=this_object(); while(o=_next(o))) |
test_do(object o=this_object(); while(o=_prev(o))) |
|
test_any([[ |
object q=class {}(); |
object o=_next(this_object()); |
while(zero_type(o)) o=_next(o); /* skip destructed */ |
catch { if(objectp(o) || object_program(o)) return 1; }; |
o=_prev(this_object()); |
while(zero_type(o)) o=_prev(o); /* skip destructed */ |
catch { if(objectp(o) || object_program(o)) return 1; }; |
return 0; |
]],1) |
|
test_any([[object(Stdio.File) o=Stdio.File(); return objectp(o);]],1) |
test_any([[object o=Regexp("foo"); return objectp(o);]],1) |
test_any([[object o=Regexp("foo"); return object_program(o);]],Regexp) |
test_any([[class Test {}; object(Test) o=Test(); return object_program(o);]],Test) |
test_define_program(test,[[constant foo = 1; int a() { return foo; }]]) |
test_true(new(test)->a()) |
test_program(inherit test;) |
test_program(inherit test; int a() { return foo; } ) |
test_define_program(test,[[class TEST { int a() { return 1; } }]]) |
test_program(inherit test; inherit TEST; ) |
|
|
test_any([[ |
/* don't save parent */ |
class Foo { }; |
return function_object(object_program(Foo())) == |
object_program(this_object()); |
]], 1) |
|
test_any([[ |
class Foo { }; |
return function_name(object_program(Foo())); |
]], "Foo") |
|
test_any([[ |
int q; |
return stringp(function_name( lambda() { return q; })); |
]],1) |
|
test_any([[ |
int q; |
return function_object( lambda() { return q; }); |
]],[[this_object()]]) |
|
|
test_compile_error(class c { object(Stdio.File) foo=class {} ();}) |
test_compile_error(class c { object(Stdio.File) foo=class {} ();}) |
test_compile_error(class c { object(Stdio.File) foo=class {} ();}) |
test_compile_error(class c { object(Stdio.File) foo=class foobar {} ();}) |
test_do(class c { object foo; object(Regexp) bar=foo; }) |
test_do(class c { object(Stdio.File) foo; object bar=foo; }) |
test_any(if(int i=1) return i; return 0;,1) |
test_compile(for(int i=0;i<100;i++) return 0;) |
test_compile(foreach(({}),mixed i){}) |
test_compile(sscanf("","",mixed foo)) |
test_compile_error(sscanf("","",float)) |
test_compile_error(sscanf("",float)) |
|
// ++ |
test_any([[int e; e++; return e;]],1) |
test_any([[int e; ++e; return e;]],1) |
test_any([[int e; return e++;]],0) |
test_any([[int e; return ++e;]],1) |
test_any([[int e; if(e++) return 0; return e;]],1) |
test_any([[string e=""; e++; return e;]],"1") |
|
// -- |
test_any([[int e; e--; return e;]],-1) |
test_any([[int e; --e; return e;]],-1) |
test_any([[int e; return e--;]],0) |
test_any([[int e; return --e;]],-1) |
test_any([[int e; if(e--) return 0; return e;]],-1) |
|
test_compile_error_any(master()->add_precompiled_program(\"/test\",compile_string(\"int foo() { return 17; }\",\"62\"))) |
|
test_any([[function f=random_seed; int t; foreach(allocate(1),t) f(t); return 1;]],1) |
test_compile([[while(0)if(0)continue;else;]]) |
test_compile([[do { break; } while (0);]]) |
test_program([[int b=1,c; int a() { c=b+2; return c==3; }]]) |
test_true([[ ("foobar"/"o") & ({ "foo" }) ]]) |
test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1) |
|
// glob |
test_false(glob("foo","bar")) |
test_true(glob("foo","foo")) |
test_true(glob("f?o","foo")) |
test_true(glob("f??","foo")) |
test_true(glob("?o?","foo")) |
test_true(glob("f*","foo")) |
test_true(glob("*o","foo")) |
test_true(glob("*<<<*","<<<")) |
test_true(glob("*<<<*","<<<foo")) |
test_false(glob("*f","foo")) |
test_false(glob("o*","foo")) |
test_false(glob("?f?","foo")) |
test_equal([[glob("?f?",({"ff","ffff","off","fff",""}))]],[[({"off","fff"})]]) |
test_equal([[glob("foo*bar",({"foobar","foobargazonk","","foofoobar","fobar","fooar"}))]],[[({"foobar","foofoobar"})]]) |
|
// localtime |
cond([[all_constants()->localtime]], |
[[ |
test_true(mappingp(localtime(0))) |
]]) |
|
cond([[all_constants()->mktime]], |
[[ |
test_true([[mktime( ([ |
"sec":58, |
"isdst":1, |
"year":98, |
"mon":3, |
"mday":26, |
"hour":1, |
"min":51 |
]))]]) |
|
test_eq([[mktime(58,51,1,26,3,98,1,0)]],[[mktime( ([ |
"sec":58, |
"isdst":1, |
"year":98, |
"mon":3, |
"mday":26, |
"hour":1, |
"min":51, |
"timezone":0, |
]) ) ]]) |
|
]]) |
|
cond([[all_constants()->localtime && all_constants()->mktime]], |
[[ |
test_any([[int x=time(); return mktime(localtime(x)) == x;]], 1) |
test_any([[int x=time(); for(int y=0;y<100;y++) if(mktime(localtime(x+y)) != x+y) return x+y; return 0;]], 0) |
]]) |
|
cond([[all_constants()->_verify_internals]], |
[[ |
test_do(_verify_internals()) |
]]) |
|
// sort |
test_equal(sort(({1,3,2,4})),({1,2,3,4})) |
test_equal(sort(({4,3,2,1})),({1,2,3,4})) |
test_equal([[lambda() {array(int) a=({1,2,3,4}); sort(({4,3,2,1}),a); return a; }()]],[[({4,3,2,1})]] ) |
test_equal([[lambda() {array(int) a=({1,2,3,4}), b=a+({}); sort(({4,3,2,1}),a,b); return b; }()]],[[({4,3,2,1})]] ) |
|
cond([[all_constants()->thread_create]], |
[[ |
// thread_create |
test_do(thread_create(lambda() { })) |
|
// /precompiled/mutex |
test_true(Thread.Mutex()) |
test_do(add_constant("_tmp_mutex",Thread.Mutex())) |
test_true(_tmp_mutex->lock()) |
test_true(_tmp_mutex->lock()) |
test_true(_tmp_mutex->trylock()) |
test_true(_tmp_mutex->trylock()) |
test_do(add_constant("_tmp_mutex_lock",_tmp_mutex->lock())) |
test_true(catch(_tmp_mutex->trylock())) |
test_do(add_constant("_tmp_mutex_lock")) |
test_true(_tmp_mutex->trylock()) |
test_do(add_constant("_tmp_mutex")) |
test_any([[ object m = Thread.Mutex(); object k = m->lock(); thread_create(lambda(object k){ sleep(10); catch { destruct(k); }; }, k);if (catch{m->lock(); return 0;}) { return 1; } return 0; ]],1) |
test_any([[ array data=({0,Thread.Mutex(),Thread.Mutex(),0}); data[3]=data[2]->lock(); thread_create(lambda(array data) {object o=data[1]->lock(); destruct(data[3]); sleep(10); data[0]=1; destruct(o); },data); object l=data[2]->lock(1); object ll=data[1]->lock(); return data[0]; ]],1) |
test_any([[ |
array data=({1, Thread.Mutex(), Thread.Condition(), 0}); |
for(int e=0;e<3;e++) { data[3]++; thread_create(lambda(mixed *data) { |
for(int e=0;e<1000;e++) { object o=data[1]->lock(); data[0]*=2; |
for(int d=0;d<5;d++) { data[0]--; data[0]*=2; } data[0]--; destruct(o); } |
data[3]--; data[2]->signal();}, data);} |
while(data[3]) data[2]->wait(); return data[0];]],1) |
|
// /precompiled/condition |
test_true(Thread.Condition()) |
test_do(Thread.Condition()->signal()) |
test_do(Thread.Condition()->broadcast()) |
|
test_true(objectp(clone(Thread.Fifo))) |
test_true(objectp(clone(Thread.Queue))) |
|
test_any([[object o=Thread.Queue(); thread_create(lambda(object f) { for(int e=0;e<10000;e++) f->write(random(4711)); f->write(-1); },o); int tmp=0; while(o->read() != -1) tmp++; return tmp;]],10000) |
test_any([[object o=Thread.Fifo(); thread_create(lambda(object f) { for(int e=0;e<10000;e++) f->write(random(4711)); f->write(-1); },o); int tmp=0; while(o->read() != -1) tmp++; return tmp;]],10000) |
|
dnl this will crash pike on out-of-address-space-related errors |
dnl test_any([[ catch { allocate(10000,thread_create)(lambda() { sleep(1); })->wait(); } ]]) |
]]) |
|
cond([[all_constants()->thread_create]], |
[[ |
// _disable_threads |
test_any([[ |
#ifndef __NT__ |
// Using a named pipe here to make open() block. That doesn't exist on NT. |
|
object t = class { |
void log (function f, string msg) |
{ |
#if 0 |
if (f == test) msg = "[T] " + msg; |
else if (f == thread_disabler) msg = " " * 20 + "[D] " + msg; |
else if (f == mutex_locker) msg = " " * 40 + "[L] " + msg; |
werror (msg); |
#endif |
} |
|
mixed err; |
|
string fifo = "/tmp/testpipe." + getpid(); |
|
int started; |
Thread.Mutex start_lock = Thread.Mutex(); |
Thread.Mutex locker_lock = Thread.Mutex(); |
Thread.Mutex locked_mutex = Thread.Mutex(); |
Thread.MutexKey locked_mutex_key; |
|
void mutex_locker() |
{ |
log (mutex_locker, "locker started\n"); |
started++; |
Thread.MutexKey k = start_lock->lock(); |
k = 0; |
|
k = locker_lock->lock(); |
k = 0; |
|
log (mutex_locker, "locker running\n"); |
err = catch (k = locked_mutex->lock()); |
log (mutex_locker, "locker done, error: " + (err && describe_error (err)) + "\n"); |
k = 0; |
} |
|
void thread_disabler() |
{ |
log (thread_disabler, "disabler started\n"); |
Thread.MutexKey locker_key = locker_lock->lock(); |
|
started++; |
Thread.MutexKey k = start_lock->lock(); |
k = 0; |
|
sleep (0.1); |
log (thread_disabler, "disabling\n"); |
locker_key = 0; |
// Race: Don't want mutex_locker to get the lock on locker_lock |
// until we're in _disable_threads. |
object disable = _disable_threads(); |
log (thread_disabler, "disabled\n"); |
sleep (0.1); |
disable = 0; |
log (thread_disabler, "disabler done\n"); |
} |
|
void test() |
{ |
locked_mutex_key = locked_mutex->lock(); |
started = 0; |
|
Thread.MutexKey start_key = start_lock->lock(); |
object disabler = thread_create (thread_disabler); |
object locker = thread_create (mutex_locker); |
while (started < 2) sleep (0.1); |
|
Process.Process writer = Process.create_process ( |
({master()->_pike_file_name, |
@(master()->_master_file_name ? |
({"-m" + master()->_master_file_name}) : ({})), |
"-e", |
sprintf ("sleep (0.5); " |
"Stdio.File f = Stdio.File (%O, \"w\"); " |
"sleep (0.5); " |
"f->close();", fifo)})); |
|
log (test, "opening pipe\n"); |
start_key = 0; |
Stdio.File f = Stdio.File (fifo, "r"); |
log (test, "pipe opened\n"); |
locked_mutex_key = 0; |
|
f->close(); |
disabler->wait(); |
locker->wait(); |
writer->wait(); |
log (test, "test done\n"); |
} |
}(); |
|
rm (t->fifo); |
Process.system ("mkfifo " + t->fifo); |
for (int i = 0; i < 5; i++) { |
t->test(); |
if (t->err) return 0; |
t->log (0, "------------\n"); |
} |
rm (t->fifo); |
|
#endif |
return 1; |
]], 1); |
]]) |
|
cond([[0]], |
[[ |
test_any([[ |
// test if read() hangs when fd is closed by other thread |
object f=Stdio.File(); |
object g=f->pipe(); |
object t=thread_create( |
lambda() |
{ |
g->read(4); |
}); |
sleep(0.1); // yield |
g->close(); // close same side of pipe as we have in read above |
sleep(0.1); // yield |
if (!t->status()) return 0; // should be done now |
// if not, there's no way to kill that thread |
return 1;]],1); |
|
]]) |
|
|
test_true(Getopt.find_option(({"","--foo"}),"p","foo")) |
test_eq(Getopt.find_option(({"","--foo=bar"}),"p","foo",0,0),"bar") |
test_eq(Getopt.find_option(({"","--foo","bar"}),"p","foo",0,0),"bar") |
test_eq(Getopt.find_option(({"","--","--foo=bar"}),"p","foo",0,0),0) |
|
test_true(Getopt.find_option(({"","-p"}),"p","foo")) |
test_eq(Getopt.find_option(({"","-pbar"}),"p","foo",0,0),"bar") |
test_eq(Getopt.find_option(({"","-p","bar"}),"p","foo",0,0),"bar") |
test_eq(Getopt.find_option(({"","--","--p","bar"}),"p","foo",0,0),0) |
|
test_equal(Getopt.get_args(({"",0,0,"sune","--","-foo"})),({"","sune","-foo"})) |
|
test_true(objectp(clone(String.String_buffer))) |
test_do(clone(String.String_buffer)->append("foo")) |
test_do(add_constant("Flurp",clone(String.String_buffer))) |
test_do(Flurp->append("test")) |
test_do(Flurp->append("test")) |
test_eq((string)Flurp,"testtest") |
test_do(add_constant("Flurp")) |
|
test_eq(String.strmult("foo",4),"foofoofoofoo") |
|
// m_delete |
test_any_equal([[ mapping m=([1:1]); m_delete(m,0); return m; ]],[[ ([1:1]) ]]) |
test_any_equal([[ mapping m=([1:1,0:3]); m_delete(m,0); return m; ]],[[ ([1:1]) ]]) |
test_any([[mapping a=([1:1]); return m_delete(a,1)]],1) |
test_any([[mapping m=([]); m[1]++; return m[1];]],1) |
test_any([[mapping m=([1:1]); m[1]++; return m[1];]],2) |
test_any([[mapping m=([]); m[1]++; m[1]++; return m[1];]],2) |
|
// multiset tests |
|
test_any([[multiset m=(<>);int e; |
for(e=0;e<1000;e++) m[e]=1; |
for(e=0;e<1000;e++) if(!m[e]) return e; |
return -1; |
]],-1) |
|
test_any([[multiset m=(<>);int e; |
for(e=0;e<1000;e++) m[e]++; |
for(e=0;e<1000;e++) if(!m[e]) return e; |
return -1; |
]],-1) |
|
test_any([[multiset m=(<>);int e; |
for(e=0;e<1000;e++) m[e]=1; |
for(e=999;e>=0;e--) if(!m[e]) return e; |
return -1; |
]],-1) |
|
test_any([[multiset m=(<>);int e; |
for(e=999;e>=0;e--) m[e]=1; |
for(e=0;e<1000;e++) if(!m[e]) return e; |
return -1; |
]],-1) |
|
test_any([[multiset m=(<>);int e; |
for(e=999;e>=0;e--) m[e]=1; |
for(e=999;e>=0;e--) if(!m[e]) return e; |
return -1; |
]],-1) |
|
test_any([[multiset m=(<>);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=1; |
for(e=0;e<1000;e++) if(!m[reverse(e)]) return e; |
return -1; |
]],-1) |
|
test_any([[multiset m=(<>);int e; |
for(e=999;e>=0;e--) m[reverse(e)]=1; |
for(e=0;e<1000;e++) if(!m[reverse(e)]) return e; |
return -1; |
]],-1) |
|
test_any([[multiset m=(<>);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=1; |
for(e=0;e<1000;e++) m[reverse(e)]=0; |
return sizeof(m); |
]],0) |
|
test_any([[multiset m=(<>);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=1; |
for(e=0;e<1000;e+=2) m[reverse(e)]=0; |
for(e=0;e<1000;e+=2) if(m[reverse(e)]) return e; |
for(e=1;e<1000;e+=2) if(!m[reverse(e)]) return e; |
return -1; |
]],-1) |
|
|
test_any([[multiset m=(<>);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=1; |
for(e=0;e<1000;e++) m[reverse(e)]++; |
for(e=0;e<1000;e++) if(m[reverse(e)]!=1) return e; |
return -1; |
]],-1) |
|
|
test_any([[multiset m=(<>);int e; |
mixed a; |
a=allocate(1000); |
for(e=0;e<1000;e++) |
{ |
m[reverse(e)]=1; |
a[e]=reverse(e); |
} |
add_constant("mtest_m",m); |
add_constant("mtest_i",a); |
return 1; |
]],1) |
|
test_any([[ |
multiset m = set_weak_flag((<>), 1); |
m[1] = 1; |
return sizeof(m); |
]], 1) |
|
test_true([[ |
multiset m = set_weak_flag((<>), 1); |
m[1] = 1; |
return get_weak_flag(m); |
]]) |
|
test_eq([[sizeof(mtest_m)]],sizeof(mtest_i)) |
test_equal(Array.sort_array(indices(mtest_m)),Array.sort_array(mtest_i)) |
test_equal(mtest_m,copy_value(mtest_m)) |
|
test_any([[multiset m=(<>);int e; |
mixed a; |
a=allocate(100); |
for(e=0;e<100;e++) |
{ |
m[reverse(e-50)]=1; |
a[e]=reverse(e-50); |
if(sizeof(m)!=e+1) return e; |
} |
add_constant("mtest_m2",m); |
add_constant("mtest_i2",a); |
return -1; |
]],-1) |
|
test_eq([[sizeof(mtest_m2)]],sizeof(mtest_i2)) |
test_any([[int e;multiset q=(<>),p=(<>); for(e=0;e<1000;e++) { p[reverse(e)]=1; q+=(<reverse(e)>); if(!equal(sort(indices(p)),sort(indices(q)))) return 0; } return 1;]],1) |
|
test_equal(sort(indices(mtest_m|mtest_m2)),sort(mtest_i|mtest_i2)) |
test_equal(sort(indices(mtest_m&mtest_m2)),sort(mtest_i&mtest_i2)) |
test_equal(sort(indices(mtest_m-mtest_m2)),sort(mtest_i-mtest_i2)) |
test_equal(sort(indices(mtest_m^mtest_m2)),sort(mtest_i^mtest_i2)) |
test_equal(sort(indices(mtest_m2|mtest_m)),sort(mtest_i2|mtest_i)) |
test_equal(sort(indices(mtest_m2&mtest_m)),sort(mtest_i2&mtest_i)) |
test_equal(sort(indices(mtest_m2-mtest_m)),sort(mtest_i2-mtest_i)) |
test_equal(sort(indices(mtest_m2^mtest_m)),sort(mtest_i2^mtest_i)) |
|
test_do(add_constant("mtest_m"); add_constant("mtest_i"); ) |
test_do(add_constant("mtest_m2"); add_constant("mtest_i2"); ) |
|
define([[MTEST]],[[test_equal([[mkmultiset(indices(allocate($1)))]],[[mkmultiset(reverse(indices(allocate($1))))]])]]) |
|
MTEST(0) |
MTEST(1) |
MTEST(2) |
MTEST(3) |
MTEST(5) |
MTEST(8) |
MTEST(13) |
MTEST(21) |
MTEST(34) |
MTEST(55) |
|
define([[MTEST]]) |
|
test_equal([[lambda(multiset x){return ({x[17]++,x[17]++,x[17]++});}((<>))]], |
[[({0,1,1})]]) |
|
// mapping tests |
|
test_any([[mapping m=([]);int e; |
for(e=0;e<1000;e++) m[e]=e; |
for(e=0;e<1000;e++) if(m[e]!=e) return 0; |
return 1; |
]],1) |
|
test_any([[mapping m=([]);int e; |
for(e=0;e<1000;e++) m[e]=e; |
for(e=999;e>=0;e--) if(m[e]!=e) return 0; |
return 1; |
]],1) |
|
|
test_any([[mapping m=([]);int e; |
for(e=999;e>=0;e--) m[e]=e; |
for(e=0;e<1000;e++) if(m[e]!=e) return 0; |
return 1; |
]],1) |
|
test_any([[mapping m=([]);int e; |
for(e=999;e>=0;e--) m[e]=e; |
for(e=999;e>=0;e--) if(m[e]!=e) return 0; |
return 1; |
]],1) |
|
|
test_any([[mapping m=([]);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=e; |
for(e=0;e<1000;e++) if(m[reverse(e)]!=e) return 0; |
return 1; |
]],1) |
|
|
test_any([[mapping m=([]);int e; |
for(e=999;e>=0;e--) m[reverse(e)]=e; |
for(e=0;e<1000;e++) if(m[reverse(e)]!=e) return 0; |
return 1; |
]],1) |
|
|
test_any([[mapping m=([]);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=e; |
for(e=0;e<1000;e++) m_delete(m,reverse(e)); |
return sizeof(m); |
]],0) |
|
test_any([[mapping m=([]);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=e; |
for(e=0;e<1000;e+=2) m_delete(m,reverse(e)); |
for(e=0;e<1000;e+=2) if(m[reverse(e)]) return 0; |
for(e=1;e<1000;e+=2) if(m[reverse(e)]!=e) return 0; |
return 1; |
]],1) |
|
test_any([[mapping m=([]);int e; |
for(e=0;e<1000;e++) m[reverse(e)]=e; |
for(e=0;e<1000;e++) m[reverse(e)]++; |
for(e=0;e<1000;e++) if(m[reverse(e)]!=e+1) return 0; |
return 1; |
]],1) |
|
test_any([[mapping m=([]);int e; |
mixed a,b; |
a=allocate(1000); |
b=allocate(1000); |
for(e=0;e<1000;e++) |
{ |
m[reverse(e)]=e; |
a[e]=reverse(e); |
b[e]=e; |
} |
add_constant("mtest_m",m); |
add_constant("mtest_i",a); |
add_constant("mtest_v",b); |
return 1; |
]],1) |
|
|
test_eq([[sizeof(mtest_m)]],sizeof(mtest_i)) |
test_equal(Array.sort_array(indices(mtest_m)),Array.sort_array(mtest_i)) |
test_equal(Array.sort_array(values(mtest_m)),Array.sort_array(mtest_v)) |
test_equal(mtest_m,copy_value(mtest_m)) |
test_any([[int e; for(e=0;e<1000;e++) if(!equal(mtest_m[mtest_i[e] ],mtest_v[e])) return 0; return 1;]],1) |
|
|
test_any([[mapping m=([]);int e; |
mixed a,b; |
a=allocate(100); |
b=allocate(100); |
for(e=0;e<100;e++) |
{ |
m[reverse(e-50)]=e-50; |
a[e]=reverse(e-50); |
b[e]=reverse(e-50); |
} |
add_constant("mtest_m2",m); |
add_constant("mtest_i2",a); |
add_constant("mtest_v2",b); |
return 1; |
]],1) |
|
test_any([[int e;mapping q=([]),p=([]); for(e=0;e<1000;e++) { p[reverse(e)]=e; q+=([reverse(e):e]); if(!equal(sort(indices(p)),sort(indices(q)))) return 0; } return 1;]],1) |
test_any([[mapping m=([]); m+=(["foo":"bar"]); m+=(["bar":"foo"]); m+=(["foo":"foo"]); if(sizeof(m)==3) return 1; return m["foo"]=="foo" && m["bar"]=="foo"]],1) |
|
test_equal(sort(indices(mtest_m|mtest_m2)),sort(mtest_i|mtest_i2)) |
test_equal(sort(indices(mtest_m&mtest_m2)),sort(mtest_i&mtest_i2)) |
test_equal(sort(indices(mtest_m-mtest_m2)),sort(mtest_i-mtest_i2)) |
test_equal(sort(indices(mtest_m^mtest_m2)),sort(mtest_i^mtest_i2)) |
test_equal(sort(indices(mtest_m2|mtest_m)),sort(mtest_i2|mtest_i)) |
test_equal(sort(indices(mtest_m2&mtest_m)),sort(mtest_i2&mtest_i)) |
test_equal(sort(indices(mtest_m2-mtest_m)),sort(mtest_i2-mtest_i)) |
test_equal(sort(indices(mtest_m2^mtest_m)),sort(mtest_i2^mtest_i)) |
|
test_do(add_constant("mtest_m"); add_constant("mtest_i"); add_constant("mtest_v");) |
test_do(add_constant("mtest_m2"); add_constant("mtest_i2"); add_constant("mtest_v2");) |
|
define([[MTEST]],[[test_equal([[mkmapping(indices(allocate($1)),reverse(indices(allocate($1))))]],[[mkmapping(reverse(indices(allocate($1))),indices(allocate($1)))]])]]) |
|
MTEST(0) |
MTEST(1) |
MTEST(2) |
MTEST(3) |
MTEST(5) |
MTEST(8) |
MTEST(13) |
MTEST(21) |
MTEST(34) |
MTEST(55) |
|
define([[MTEST]]) |
|
test_do([[ |
|
class X { |
mapping gurka; |
|
class Tomat |
{ |
int `==(mixed x) |
{ |
/* make hash bigger */ |
for(int e=sizeof(gurka);e<1000;e++) gurka[e]=e; |
return 0; |
} |
|
int __hash() |
{ |
return 99999; |
} |
}; |
|
class Sallad |
{ |
int __hash() |
{ |
return 99999; |
} |
}; |
|
void create() |
{ |
for(int x=1;x<255;x++) |
{ |
gurka=([]); |
for(int e=0;e<x;e++) gurka[~e]=e; |
gurka[Sallad()]=-2; |
gurka[Tomat()]=-3; |
} |
} |
}(); |
|
]]) |
|
test_equal([[ `+( ([1:2]) )]],[[ ([1:2]) ]]) |
test_false( `+( ([1:2]) ) == ([1:2]) ) |
test_equal([[ `+( ([1:2]), ([1:2]) )]],[[ ([1:2]) ]]) |
test_equal([[ `+( ([1:2]), ([1:2]), ([2:3,4:5]) )]],[[ ([1:2,2:3,4:5]) ]]) |
test_equal([[ `+( ([1:2]), ([1:2]), ([2:3,4:5]), ([6:7,1:2]) )]],[[ ([1:2,2:3,4:5,6:7]) ]]) |
test_equal([[ `+( ([1:2]), ([1:2]), ([2:3,4:5]), ([6:7,1:2]),([8:9]) )]],[[ ([1:2,2:3,4:5,6:7,8:9]) ]] ) |
|
test_any([[mapping m=([1:2,3:2]); return search(m,2,search(m,2))!=-1;]],1) |
|
test_any([[mapping m=([]); for(int e=0;e<1000;e++) m[e&3]+=({e}); return sizeof(m)==4 && sizeof(m[0])==250;]],1) |
|
test_any([[ |
mapping m = set_weak_flag (([1:1]), 1); |
m_delete (m, 1); |
return get_weak_flag (([])); |
]], 0); |
|
test_equal([[lambda(mapping x){return ({x[17]++,x[17]++,x[17]++});}(([]))]], |
[[({0,1,2})]]) |
|
// destructed indices |
test_any([[{ |
object o = class{}(); |
mapping m = ([o: 1]); |
destruct (o); |
return equal (m, ([])) && equal (m, ([])); |
}]], 1) |
test_any([[{ |
object o = class{}(); |
mapping m = ([o: 1]), n = ([class{}(): 1]); |
destruct (o); |
return !equal (m, n) && !equal (m, n); |
}]], 1) |
test_any([[{ |
object o = class{}(); |
mapping m = ([o: 1]); |
destruct (o); |
return sizeof (indices (m)) || sizeof (m); |
}]], 0) |
test_any([[{ |
object o = class{}(); |
mapping m = ([o: 1]); |
destruct (o); |
return sizeof (values (m)) || sizeof (m); |
}]], 0) |
|
// rows |
test_equal([[rows(({1,2,3,4,5,6,7,8,9}),({6,7,2}))]],[[({7,8,3})]]) |
test_equal([[rows(({1,2,3,4,5,6,7,8,9}),({0,4,1}))]],[[({1,5,2})]]) |
test_equal([[rows(({1,2,3,4,5,6,7,8,9}),({8,3,5}))]],[[({9,4,6})]]) |
|
// column |
test_equal([[column(({({1,2,3}),({5,6,7}),({8,9,0})}),0)]],[[({1,5,8})]]) |
test_equal([[column(({({1,2,3}),({5,6,7}),({8,9,0})}),1)]],[[({2,6,9})]]) |
test_equal([[column(({({1,2,3}),({5,6,7}),({8,9,0})}),2)]],[[({3,7,0})]]) |
|
|
// gc |
ifefun(gc, |
[[ |
test_true(intp(gc())); |
test_any([[ array a=({0}); a[0]=a; gc(); a=0; return gc() > 0; ]],1); |
test_any([[object o=class c {object o;}(); o->o=o; gc(); o=0; return gc() > 0; ]],1); |
test_any([[object o=class c {object o;}(); o->o=o; gc(); o=0; return gc() > 0; ]],1); |
test_any([[mapping m=([]); m[m]=m; gc(); m=0; return gc() > 0; ]],1); |
test_any([[multiset m=(<>); m[m]=1; gc(); m=0; return gc() > 0; ]],1); |
test_any([[{ |
#if !constant (_debug) |
int _debug (int d) {return 0;}; |
#endif |
// Must turn off debug in this test or else we'll get extra |
// references to p in the backlog. |
int dlevel = _debug (0); |
program p=compile_string("constant a=({0});"); |
object o=p(); |
o->a[0]=p; |
gc(); |
p=o=0; |
_debug (dlevel); |
return gc() > 0; |
}]], 1); |
|
test_any([[gc(); |
int q=lambda() { mixed foo; foo=lambda() { return foo; }; return 1; }(); |
return gc()>0; |
]],1) |
|
test_true([[ |
object o = class{}(); |
mapping m = ([class{}(): o, o: class{}()]); |
set_weak_flag (m, 1); |
gc(); |
return !sizeof (m); |
]]) |
test_true([[ |
object o = class{}(); |
mapping m = ([class{}(): o, o: class{}()]); |
set_weak_flag (m, Pike.WEAK_INDICES); |
gc(); |
return sizeof (m); |
]]) |
test_true([[ |
object o = class{}(); |
|