summaryrefslogtreecommitdiffstats
path: root/sca-cpp/branches/lightweight-sca/kernel/kernel-test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/branches/lightweight-sca/kernel/kernel-test.cpp')
-rw-r--r--sca-cpp/branches/lightweight-sca/kernel/kernel-test.cpp614
1 files changed, 614 insertions, 0 deletions
diff --git a/sca-cpp/branches/lightweight-sca/kernel/kernel-test.cpp b/sca-cpp/branches/lightweight-sca/kernel/kernel-test.cpp
new file mode 100644
index 0000000000..4d2ca2ba81
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/kernel/kernel-test.cpp
@@ -0,0 +1,614 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test kernel functions.
+ */
+
+#include <assert.h>
+#include "string.hpp"
+#include "sstream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "tree.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "dynlib.hpp"
+#include "perf.hpp"
+
+namespace tuscany {
+
+struct inc {
+ int i;
+ inc(int i) :
+ i(i) {
+ }
+ const int operator()(const int x) const {
+ return x + i;
+ }
+};
+
+const int square(const int x) {
+ return x * x;
+}
+
+int mapLambda(lambda<int(const int)> f, int v) {
+ return f(v);
+}
+
+bool testLambda() {
+ const lambda<int(const int)> sq(square);
+ assert(sq(2) == 4);
+ assert(mapLambda(sq, 2) == 4);
+ assert(mapLambda(square, 2) == 4);
+
+ const lambda<int(const int)> incf(inc(10));
+ assert(incf(1) == 11);
+ assert(mapLambda(incf, 1) == 11);
+ assert(mapLambda(inc(10), 1) == 11);
+
+ lambda<int(const int)> l;
+ l = incf;
+ assert(l(1) == 11);
+ l = square;
+ assert(l(2) == 4);
+ return true;
+}
+
+bool testLambdaGC() {
+ resetLambdaCounters();
+ {
+ gc_scoped_pool gc;
+ testLambda();
+ }
+ assert(checkLambdaCounters());
+ return true;
+}
+
+int countElements = 0;
+
+struct Element {
+ int i;
+
+ Element() : i(0) {
+ countElements++;
+ }
+
+ Element(int i) : i(i) {
+ countElements++;
+ }
+
+ Element(const Element& o) : i(o.i) {
+ countElements++;
+ }
+
+ ~Element() {
+ countElements--;
+ }
+
+ const bool operator==(const Element& o) const {
+ return o.i == i;
+ }
+};
+ostream& operator<<(ostream& out, const Element& v) {
+ out << v.i ;
+ return out;
+}
+
+bool testCons() {
+ assert(car(cons(2, mklist(3))) == 2);
+ assert(car(cdr(cons(2, mklist(3)))) == 3);
+ assert(isNil(cdr(cdr(cons(2, mklist(3))))));
+
+ assert(cons(Element(1), mklist(Element(2))) == mklist(Element(1), Element(2)));
+ return true;
+}
+
+bool testListGC() {
+ resetLambdaCounters();
+ resetListCounters();
+ countElements = 0;
+ {
+ gc_scoped_pool gc;
+ testCons();
+ }
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
+ assert(countElements == 0);
+ return true;
+}
+
+bool testOut() {
+ ostringstream os1;
+ os1 << list<int> ();
+ assert(str(os1) == "()");
+
+ ostringstream os2;
+ os2 << mklist(1, 2, 3);
+ assert(str(os2) == "(1 2 3)");
+ return true;
+}
+
+bool testEquals() {
+ assert(list<int>() == list<int>());
+ assert(mklist(1, 2) == mklist(1, 2));
+ assert(list<int>() != mklist(1, 2));
+ assert(mklist(1, 2, 3) == mklist(1, 2, 3));
+ assert(mklist(1, 2) != mklist(1, 2, 3));
+ return true;
+}
+
+bool testLength() {
+ assert(0 == length(list<int>()));
+ assert(1 == length(mklist(1)));
+ assert(2 == length(cons(1, mklist(2))));
+ return true;
+}
+
+bool testAppend() {
+ assert(car(append(mklist(1), mklist(2))) == 1);
+ assert(car(cdr(append(mklist(1), mklist(2)))) == 2);
+ assert(car(cdr(cdr(append(mklist(1), mklist(2, 3))))) == 3);
+ assert(isNil(cdr(cdr(cdr(append(mklist(1), mklist(2, 3)))))));
+
+ assert(list<int>() + 1 + 2 + 3 == mklist(1, 2, 3));
+ return true;
+}
+
+struct Complex {
+ int x;
+ int y;
+ Complex() {
+ }
+ Complex(int x, int y) :
+ x(x), y(y) {
+ }
+};
+ostream& operator<<(ostream& out, const Complex& v) {
+ out << "[" << v.x << ":" << v.y << "]";
+ return out;
+}
+
+bool testComplex() {
+ const list<Complex> p = mklist(Complex(1, 2), Complex(3, 4));
+ assert(car(p).x == 1);
+ assert(car(cdr(p)).x == 3);
+ assert(isNil(cdr(cdr(p))));
+ return true;
+}
+
+bool testMap() {
+ assert(isNil(map<int, int>(square, list<int>())));
+
+ const list<int> m = map<int, int>(square, mklist(2, 3));
+ assert(car(m) == 4);
+ assert(car(cdr(m)) == 9);
+
+ return true;
+}
+
+const int add(const int x, const int y) {
+ return x + y;
+}
+
+bool testReduce() {
+ const lambda<int(const int, const int)> r(add);
+ assert(reduce(r, 0, mklist(1, 2, 3)) == 6);
+ return true;
+}
+
+bool isPositive(const int x) {
+ if(x >= 0)
+ return true;
+ else
+ return false;
+}
+
+bool testFilter() {
+ assert(car(filter<int>(isPositive, mklist(1, -1, 2, -2))) == 1);
+ assert(cadr(filter<int>(isPositive, mklist(1, -1, 2, -2))) == 2);
+ return true;
+}
+
+bool testMember() {
+ assert(isNil(member(4, mklist(1, 2, 3))));
+ assert(car(member(1, mklist(1, 2, 3))) == 1);
+ assert(car(member(2, mklist(1, 2, 3))) == 2);
+ assert(car(member(3, mklist(1, 2, 3))) == 3);
+ return true;
+}
+
+bool testReverse() {
+ assert(isNil(reverse(list<int>())));
+ assert(car(reverse(mklist(1, 2, 3))) == 3);
+ assert(cadr(reverse(mklist(1, 2, 3))) == 2);
+ return true;
+}
+
+bool testListRef() {
+ assert(listRef(mklist(1), 0) == 1);
+ assert(listRef(mklist(1, 2, 3), 0) == 1);
+ assert(listRef(mklist(1, 2, 3), 1) == 2);
+ assert(listRef(mklist(1, 2, 3), 2) == 3);
+ return true;
+}
+
+bool testAssoc() {
+ const list<list<string> > l = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
+ assert(assoc<string>("a", l) == mklist<string>("a", "A"));
+ assert(isNil(assoc<string>("z", l)));
+
+ const list<list<value> > u = mklist(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
+ assert(assoc<value>("a", u) == mklist<value>("a", "A"));
+
+ const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
+ assert(assoc<value>("a", v) == mklist<value>("a", "A"));
+ return true;
+}
+
+bool testZip() {
+ const list<string> k = mklist<string>("x", "a", "y", "a");
+ const list<string> v = mklist<string>("X", "A", "Y", "AA");
+ const list<list<string> > z = mklist(k, v);
+ const list<list<string> > u = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
+ assert(zip(k, v) == u);
+ assert(unzip(u) == z);
+ return true;
+}
+
+bool testTokenize() {
+ assert(tokenize("/", "") == list<string>());
+ assert(tokenize("/", "aaa") == mklist<string>("aaa"));
+ assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist<string>("aaa", "bbb", "ccc", "ddd"));
+ assert(tokenize("/", "/bbb/ccc/ddd") == mklist<string>("", "bbb", "ccc", "ddd"));
+ assert(tokenize("/", "/bbb/ccc/") == mklist<string>("", "bbb", "ccc"));
+ assert(tokenize("/", "/bbb//ccc/") == mklist<string>("", "bbb", "", "ccc"));
+ assert(tokenize("/", "abc/def/") == mklist<string>("abc", "def"));
+
+ assert(join("/", list<string>()) == "");
+ assert(join("/", mklist<string>("aaa")) == "aaa");
+ assert(join("/", mklist<string>("aaa", "bbb", "ccc", "ddd")) == "aaa/bbb/ccc/ddd");
+ assert(join("/", mklist<string>("", "bbb", "ccc", "ddd")) == "/bbb/ccc/ddd");
+ assert(join("/", mklist<string>("bbb", "ccc", "")) == "bbb/ccc/");
+ assert(join("/", mklist<string>("bbb", "", "ccc")) == "bbb//ccc");
+ return true;
+}
+
+double testSeqMap(double x) {
+ return x;
+}
+
+double testSeqReduce(unused double v, double accum) {
+ return accum + 1.0;
+}
+
+bool testSeq() {
+ resetLambdaCounters();
+ resetListCounters();
+
+ list<double> s = seq(0.0, 1000.0);
+ assert(1001 == length(s));
+
+ assert(1001 == length(map<double, double>(testSeqMap, s)));
+
+ assert(801 == length(member(200.0, s)));
+ assert(201 == length(member(200.0, reverse(s))));
+
+ assert(1001 == (reduce<double, double>(testSeqReduce, 0.0, s)));
+ return true;
+}
+
+value valueSquare(list<value> x) {
+ return (int)car(x) * (int)car(x);
+}
+
+bool testValue() {
+ assert(value(true) == value(true));
+ assert(value(1) == value(1));
+ assert(value("abcd") == value("abcd"));
+ lambda<value(const list<value>&)> vl(valueSquare);
+ assert(value(vl) == value(vl));
+ assert(value(mklist<value>(1, 2)) == value(mklist<value>(1, 2)));
+
+ const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"));
+ assert(cadr((list<list<value> >)value(v)) == mklist<value>("a", "A"));
+
+ const value pv(gc_ptr<value>(new (gc_new<value>()) value(1)));
+ assert(*(gc_ptr<value>)pv == value(1));
+
+ const list<value> lpv = mklist<value>(gc_ptr<value>(new (gc_new<value>()) value(1)), gc_ptr<value>(new (gc_new<value>()) value(2)));
+ assert(*(gc_ptr<value>)car(lpv) == value(1));
+ return true;
+}
+
+bool testValueGC() {
+ resetLambdaCounters();
+ resetListCounters();
+ resetValueCounters();
+ {
+ gc_scoped_pool gc;
+ testValue();
+ }
+ assert(checkValueCounters());
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
+ return true;
+}
+
+bool testTree() {
+ const list<value> t = mktree<value>("a", list<value>(), list<value>());
+ const list<value> ct = constree<value>("d", constree<value>("f", constree<value>("c", constree<value>("e", constree<value>("b", t)))));
+ const list<value> mt = mktree(mklist<value>("d", "f", "c", "e", "b", "a"));
+ assert(mt == ct);
+ const list<value> l = flatten<value>(mt);
+ assert(length(l) == 6);
+ assert(car(l) == "a");
+ assert(car(reverse(l)) == "f");
+ const list<value> bt = mkbtree<value>(l);
+ assert(car(bt) == "c");
+ return true;
+}
+
+const list<value> lta(const string& x) {
+ return mklist<value>(c_str(x), c_str(x + x));
+}
+
+bool testTreeAssoc() {
+ const list<value> t = mktree<value>(lta("a"), list<value>(), list<value>());
+ const list<value> at = constree<value>(lta("d"), constree<value>(lta("f"), constree<value>(lta("c"), constree<value>(lta("e"), constree<value>(lta("b"), t)))));
+ const list<value> l = flatten<value>(at);
+ assert(length(l) == 6);
+ assert(car(l) == mklist<value>("a", "aa"));
+ assert(car(reverse(l)) == mklist<value>("f", "ff"));
+ const list<value> bt = mkbtree<value>(l);
+ assert(car(bt) == mklist<value>("c", "cc"));
+ assert(assoctree<value>("a", bt) == mklist<value>("a", "aa"));
+ assert(assoctree<value>("b", bt) == mklist<value>("b", "bb"));
+ assert(assoctree<value>("f", bt) == mklist<value>("f", "ff"));
+ assert(isNil(assoctree<value>("x", bt)));
+ return true;
+}
+
+double fib_aux(double n, double a, double b) {
+ if(n == 0.0)
+ return a;
+ return fib_aux(n - 1.0, b, a + b);
+}
+
+double fib(double n) {
+ return fib_aux(n, 0.0, 1.0);
+}
+
+struct fibMapPerf {
+ const bool operator()() const {
+ list<double> s = seq(0.0, 999.0);
+ list<double> r = map<double, double>(fib, s);
+ assert(1000 == length(r));
+ return true;
+ }
+};
+
+struct nestedFibMapPerf {
+ const lambda<double(const double)> fib;
+ nestedFibMapPerf(const lambda<double(const double)>& fib) : fib(fib) {
+ }
+ const bool operator()() const {
+ list<double> s = seq(0.0, 999.0);
+ list<double> r = map<double, double>(fib, s);
+ assert(1000 == length(r));
+ return true;
+ }
+};
+
+bool testCppPerf() {
+ {
+ const lambda<bool()> fml = fibMapPerf();
+ cout << "Fibonacci map test " << (time(fml, 1, 1) / 1000) << " ms" << endl;
+ }
+
+ {
+ struct nested {
+ static double fib(double n) {
+ struct nested {
+ static double fib_aux(double n, double a, double b) {
+ if(n == 0.0)
+ return a;
+ return fib_aux(n - 1.0, b, a + b);
+ }
+ };
+ return nested::fib_aux(n, 0.0, 1.0);
+ }
+ };
+
+ const lambda<bool()> nfml = nestedFibMapPerf(lambda<double(const double)>(nested::fib));
+ cout << "Nested Fibonacci map test " << (time(nfml, 1, 1) / 1000) << " ms" << endl;
+ }
+ return true;
+}
+
+const id<int> idF(const int v) {
+ return v * 2;
+}
+
+const id<int> idG(const int v) {
+ return v * 3;
+}
+
+const id<int> idH(const int v) {
+ return idF(v) >> idG;
+}
+
+bool testIdMonad() {
+ const id<int> m(2);
+ assert(m >> idF == idF(2));
+ assert(m >> unit<int>() == m);
+ assert(m >> idF >> idG == m >> idH);
+ return true;
+}
+
+const maybe<int> maybeF(const int v) {
+ return v * 2;
+}
+
+const maybe<int> maybeG(const int v) {
+ return v * 3;
+}
+
+const maybe<int> maybeH(const int v) {
+ return maybeF(v) >> maybeG;
+}
+
+bool testMaybeMonad() {
+ const maybe<int> m(2);
+ assert(m >> maybeF == maybeF(2));
+ assert((m >> just<int>()) == m);
+ assert(m >> maybeF >> maybeG == m >> maybeH);
+
+ assert(maybe<int>() >> maybeF >> maybeG == maybe<int>());
+ return true;
+}
+
+const failable<int> failableF(const int v) {
+ return v * 2;
+}
+
+const failable<int> failableG(const int v) {
+ return v * 3;
+}
+
+const failable<int> failableH(const int v) {
+ return failableF(v) >> failableG;
+}
+
+bool testFailableMonad() {
+ const failable<int> m(2);
+ assert(m >> failableF == failableF(2));
+ assert((m >> success<int, string, int>()) == m);
+ assert(m >> failableF >> failableG == m >> failableH);
+
+ cout << "Failable monad test... " << endl;
+ const failable<int> ooops = mkfailure<int>("test", 500);
+ assert(reason(ooops) == "test");
+ assert(rcode(ooops) == 500);
+ assert(ooops >> failableF >> failableG == ooops);
+
+ const failable<value> vooops = mkfailure<value>(ooops);
+ assert(reason(vooops) == "test");
+ assert(rcode(vooops) == 500);
+
+ const value v = value(vooops);
+ assert(car<value>(v) == value());
+ assert(cadr<value>(v) == string("test"));
+ assert(caddr<value>(v) == value((double)500));
+ return true;
+}
+
+struct tickInc {
+ const double v;
+ tickInc(const double v) : v(v) {
+ }
+ const scp<int, double> operator()(int s) const {
+ return scp<int, double>(s + 1, v);
+ }
+};
+
+const state<int, double> tick(const double v) {
+ return transformer<int, double>(tickInc(v));
+}
+
+const state<int, double> stateF(const double v) {
+ return result<int, double>(v * 2.0) >> tick;
+}
+
+const state<int, double> stateG(const double v) {
+ return result<int, double>(v + 5);
+}
+
+const state<int, double> stateH(const double v) {
+ return stateF(v) >> stateG;
+}
+
+bool testStateMonad() {
+ const lambda<state<int, double>(const double)> r(result<int, double>);
+
+ state<int, double> m = result<int, double>(2.0);
+ assert((m >> stateF)(0) == stateF(2.0)(0));
+ assert(1 == (int)(m >> stateF)(0));
+ assert((m >> r)(0) == m(0));
+ assert((m >> stateF >> stateG)(0) == (m >> stateH)(0));
+
+ return true;
+}
+
+bool testDynLib() {
+ const lib dl(string("./libdynlib-test") + dynlibExt);
+ const failable<lambda<int(const int)> > sq(dynlambda<int(const int)>("csquare", dl));
+ assert(hasContent(sq));
+ lambda<int(const int)> l(content(sq));
+ assert(l(2) == 4);
+
+ const failable<lambda<lambda<int(const int)>()> > sql(dynlambda<lambda<int(const int)>()>("csquarel", dl));
+ assert(hasContent(sql));
+ lambda<lambda<int(const int)>()> ll(content(sql));
+ assert(ll()(3) == 9);
+ return true;
+}
+
+}
+
+int main() {
+ tuscany::gc_scoped_pool p;
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::testLambda();
+ tuscany::testLambdaGC();
+ tuscany::testCons();
+ tuscany::testListGC();
+ tuscany::testOut();
+ tuscany::testEquals();
+ tuscany::testLength();
+ tuscany::testAppend();
+ tuscany::testComplex();
+ tuscany::testMap();
+ tuscany::testReduce();
+ tuscany::testFilter();
+ tuscany::testMember();
+ tuscany::testReverse();
+ tuscany::testListRef();
+ tuscany::testAssoc();
+ tuscany::testZip();
+ tuscany::testTokenize();
+ tuscany::testSeq();
+ tuscany::testValue();
+ tuscany::testValueGC();
+ tuscany::testTree();
+ tuscany::testTreeAssoc();
+ tuscany::testCppPerf();
+ tuscany::testIdMonad();
+ tuscany::testMaybeMonad();
+ tuscany::testFailableMonad();
+ tuscany::testStateMonad();
+ tuscany::testDynLib();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}