#include "def.h"
#include "macro.h"

int test_bintree_insert_copy(void) {
  /* A reimplementation of the old test_bintree() from src/bi.c that
   * verifies the result */
  int result = 0;

  OP a = callocobject();
  OP b = callocobject();
  OP c = callocobject();
  OP a_len = callocobject();
  OP c_len = callocobject();

  /* new empty bintree */
  printf("testing bintree init...");
  if (!init_bintree(a)) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  /* insert 5 */
  m_i_i(5L, b);
  printf("testing bintree insert 5...");
  if (insert_bintree(b, a, NULL, NULL) == INSERTOK) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  /* insert 7 */
  b = callocobject();
  m_i_i(7, b);
  printf("testing bintree insert 7...");
  if (insert_bintree(b, a, NULL, NULL) == INSERTOK) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  /* copy a to c */
  printf("testing bintree copy...");
  if (!copy_bintree(a, c)) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  /* insert 9 into c (but not a) */
  b = callocobject();
  m_i_i(9, b);
  printf("testing bintree insert 9...");
  if (insert_bintree(b, c, NULL, NULL) == INSERTOK) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  /* Now, hopefully,  a=[5, 7] and c=[5, 7, 9]. Convert
   * them both to lists, and check. */
    printf("testing first bintree to list...");
  if (!t_BINTREE_LIST(a,a)) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  printf("testing second bintree to list...");
  if (!t_BINTREE_LIST(c,c)) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  printf("testing first list contents...");
  length_list(a, a_len);
  if (S_I_I(S_L_S(a)) == 5 &&
      S_I_I(S_L_S(S_L_N(a))) == 7 &&
      S_I_I(a_len) == 2) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
    goto end;
  }

  printf("testing second list contents...");
  length_list(c, c_len);
  if (S_I_I(S_L_S(c)) == 5 &&
      S_I_I(S_L_S(S_L_N(c))) == 7 &&
      S_I_I(S_L_S(S_L_N(S_L_N(c)))) == 9 &&
      S_I_I(c_len) == 3) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
  }

 end:
  /* freeing a and c frees all the bs */
  freeall(a);
  freeall(a_len);
  freeall(c);
  freeall(c_len);
  return result;
}

int test_fakul(int x) {
  int result = 0;
  OP a = callocobject();
  OP b = callocobject();

  printf("testing fakul(11)...");
  M_I_I(11, a);
  fakul(a,b);
  if (S_I_I(b) == 39916800) {
    printf("success\n");
  }
  else {
    printf("failed\n");
    result = 1;
  }
  freeall(a);
  freeall(b);
  return result;
}


int test_brauer_char(void) {
  /* modeled on test_brc, but with a fixed group and prime */
  /*
   * gap> t:=CharacterTable("S5") mod 3;
   * BrauerTable( "A5.2", 3 )
   * gap> Irr(t);
   * [ Character( BrauerTable( "A5.2", 3 ), [ 1, 1, 1, 1, 1 ] ),
   *   Character( BrauerTable( "A5.2", 3 ), [ 1, 1, 1, -1, -1 ] ),
   *   Character( BrauerTable( "A5.2", 3 ), [ 6, -2, 1, 0, 0 ] ),
   *   Character( BrauerTable( "A5.2", 3 ), [ 4, 0, -1, 2, 0 ] ),
   *   Character( BrauerTable( "A5.2", 3 ), [ 4, 0, -1, -2, 0 ] ) ]
   */
  int result = 0;
  OP prime = callocobject();
  OP sn = callocobject();
  OP actual = callocobject();

  printf("testing brauer_char(S5,3))...");
  M_I_I(5, sn);
  M_I_I(3, prime);

  int expected[] = {1,1,1,1,1,-1,0,0,2,4,1,-1,1,-1,1,1,0,-2,0,6,-1,0,0,-2,4};

  int bcres = brauer_char(sn,prime,actual);
  if (bcres != OK) {
    printf("failed (%d)\n", bcres);
    result = 1;
  }
  else{
    /* check the answer entry by entry */
    for (int i = 0; i < 5; i++) {
      for (int j = 0; j <5; j++) {
	printf(".");
	if (expected[5*i+j] != S_I_I(S_M_IJ(actual,i,j))) {
	  /* actual and expected mismatch */
	  result = 1;
	}
      }
    }
  }

  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(prime);
  freeall(sn);
  freeall(actual);
  return result;
}


int test_mult_schur_schur(void) {
  /*
   * Ensure that this bug in mult_schur_schur() is fixed:
   *
   *   - https://github.com/sagemath/sage/issues/15397
   *   - https://github.com/sagemath/sage/issues/15407
   *
   * The expected output can be checked with lrcalc:
   *
   *   sage: import sage.libs.lrcalc.lrcalc as lrcalc
   *   sage: sage.libs.lrcalc.lrcalc.mult([122,1],[2,1])
   *   {[122, 2, 1, 1]: 1,
   *    [122, 2, 2]: 1,
   *    [122, 3, 1]: 1,
   *    [123, 1, 1, 1]: 1,
   *    [123, 2, 1]: 2,
   *    [123, 3]: 1,
   *    [124, 1, 1]: 1,
   *    [124, 2]: 1}
   *
   */
  int result = 0;
  OP v = callocobject();        /* vector to build partitions */
  OP p = callocobject();        /* temporary partitions */
  OP k;                         /* temporary integers */
  OP a = callocobject();        /* function arg1 */
  OP b = callocobject();        /* function arg2 */
  OP actual = callocobject();   /* the actual result */
  OP expected = callocobject(); /* the expected result */

  /* build the expected SCHUR object,
   *
   *   1 111|123  1 112|122  1 11|124  2 12|123  1 13|122
   *   1 22|122  1 2|124 1 3|123
   *
   * from tail to head */
  m_il_v(2, v);
  M_I_I(3, S_V_I(v, 0));
  M_I_I(123, S_V_I(v, 1));
  m_v_pa(v, p);
  NEW_INTEGER(k,1);
  m_skn_s(p, k, NULL, expected);

  m_il_v(2, v);
  M_I_I(2,   S_V_I(v, 0));
  M_I_I(124, S_V_I(v, 1));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(2,   S_V_I(v, 0));
  M_I_I(2,   S_V_I(v, 1));
  M_I_I(122, S_V_I(v, 2));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(3,   S_V_I(v, 1));
  M_I_I(122, S_V_I(v, 2));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(2,   S_V_I(v, 1));
  M_I_I(123, S_V_I(v, 2));
  m_v_pa(v, p);
  M_I_I(2, k);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(1,   S_V_I(v, 1));
  M_I_I(124, S_V_I(v, 2));
  m_v_pa(v, p);
  M_I_I(1, k);
  m_skn_s(p, k, expected, expected);

  m_il_v(4, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(1,   S_V_I(v, 1));
  M_I_I(2,   S_V_I(v, 2));
  M_I_I(122, S_V_I(v, 3));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);

  m_il_v(4, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(1,   S_V_I(v, 1));
  M_I_I(1,   S_V_I(v, 2));
  M_I_I(123, S_V_I(v, 3));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);
  /* done building the expected output, now do the input */

  /* create a vector [1,122] and then make a partition out of it */
  m_il_v(2, v);
  M_I_I(1, S_V_I(v, 0));
  M_I_I(122, S_V_I(v, 1));
  m_v_pa(v, a);

  /* create a vector [1,2] and then make a partition out of it */
  M_I_I(1, S_V_I(v, 0));
  M_I_I(2, S_V_I(v, 1));
  m_v_pa(v, b);

  printf("testing mult_schur_schur([1,122],[1,2])...");
  if (mult_schur_schur(a, b, actual)) {
    result = 1;
    printf("failed\n");
  }
  else {
    if (eq(actual,expected)) {
      printf("success\n");
    }
    else {
      result = 1;
      printf("failed\n");
    }
  }

  freeall(v);
  freeall(p);
  freeall(k);
  freeall(a);
  freeall(b);
  freeall(expected);
  freeall(actual);

  return result;
}


int test_mult_schur_schur2(void) {
  /*
   * Akin to test_mult_schur_schur(), but we now test that partitions
   * larger than the maximum unsigned char value work.
   *
   * The expected output can be checked with lrcalc:
   *
   *   sage: import sage.libs.lrcalc.lrcalc as lrcalc
   *   sage: sage.libs.lrcalc.lrcalc.mult([900,1],[2,1])
   *   {[900, 3, 1]: 1,
   *    [902, 2]: 1,
   *    [901, 1, 1, 1]: 1,
   *    [901, 3]: 1,
   *    [900, 2, 1, 1]: 1,
   *    [900, 2, 2]: 1,
   *    [902, 1, 1]: 1,
   *    [901, 2, 1]: 2}
   *
   */
  int result = 0;
  OP v = callocobject();        /* vector to build partitions */
  OP p = callocobject();        /* temporary partitions */
  OP k;                         /* temporary integers */
  OP a = callocobject();        /* function arg1 */
  OP b = callocobject();        /* function arg2 */
  OP actual = callocobject();   /* the actual result */
  OP expected = callocobject(); /* the expected result */

  /* build the expected SCHUR object,
   *
   * 1 111|901  1 112|900  1 11|902  2 12|901  1 13|900  1 22|900
   * 1 2|902 1 3|901
   *
   * from tail to head.
   */
  m_il_v(2, v);
  M_I_I(3, S_V_I(v, 0));
  M_I_I(901, S_V_I(v, 1));
  m_v_pa(v, p);
  NEW_INTEGER(k,1);
  m_skn_s(p, k, NULL, expected);

  m_il_v(2, v);
  M_I_I(2, S_V_I(v, 0));
  M_I_I(902, S_V_I(v, 1));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(2,   S_V_I(v, 0));
  M_I_I(2,   S_V_I(v, 1));
  M_I_I(900, S_V_I(v, 2));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(3,   S_V_I(v, 1));
  M_I_I(900, S_V_I(v, 2));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(2,   S_V_I(v, 1));
  M_I_I(901, S_V_I(v, 2));
  m_v_pa(v, p);
  M_I_I(2, k);
  m_skn_s(p, k, expected, expected);

  m_il_v(3, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(1,   S_V_I(v, 1));
  M_I_I(902, S_V_I(v, 2));
  m_v_pa(v, p);
  M_I_I(1, k);
  m_skn_s(p, k, expected, expected);

  m_il_v(4, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(1,   S_V_I(v, 1));
  M_I_I(2,   S_V_I(v, 2));
  M_I_I(900, S_V_I(v, 3));
  m_v_pa(v, p);
  M_I_I(1, k);
  m_skn_s(p, k, expected, expected);

  m_il_v(4, v);
  M_I_I(1,   S_V_I(v, 0));
  M_I_I(1,   S_V_I(v, 1));
  M_I_I(1,   S_V_I(v, 2));
  M_I_I(901, S_V_I(v, 3));
  m_v_pa(v, p);
  m_skn_s(p, k, expected, expected);
  /* done building the expected output, now do the input */

  /* create a vector [1,900] and then make a partition out of it */
  m_il_v(2, v);
  M_I_I(1, S_V_I(v, 0));
  M_I_I(900, S_V_I(v, 1));
  m_v_pa(v, a);

  /* create a vector [1,2] and then make a partition out of it */
  M_I_I(1, S_V_I(v, 0));
  M_I_I(2, S_V_I(v, 1));
  m_v_pa(v, b);

  printf("testing mult_schur_schur([1,900],[1,2])...");
  if (mult_schur_schur(a, b, actual)) {
    result = 1;
    printf("failed\n");
  }
  else {
    if (eq(actual,expected)) {
      printf("success\n");
    }
    else {
      result = 1;
      printf("failed\n");
    }
  }

  freeall(v);
  freeall(p);
  freeall(k);
  freeall(a);
  freeall(b);
  freeall(expected);
  freeall(actual);

  return result;
}



int test_first(void) {
  /* Ensure that we can call first() with two equal arguments.
   * In other words, make sure Gitlab issue #7 is fixed.
   */
  int result = 0;
  OP z;                         /* integer to partition */
  OP expected = callocobject(); /* expected result */
  OP actual = callocobject();   /* actual result */

  /* This won't change */
  NEW_INTEGER(z, 7);

  /* Test first() for a PARTITION with two unequal arguments, and then
   * again with two equal arguments. */
  first_partition(z, expected); /* expected partition */

  printf("testing first partition (unequal args)...");
  first(PARTITION, actual, z);
  if (eq(actual,expected)) {
    printf("success\n");
  }
  else {
    result = 1;
    printf("failed\n");
    goto end;
  }
  freeall(actual);

  NEW_INTEGER(actual, 7);
  printf("testing first partition (equal args)...");
  first(PARTITION, actual, actual);
  if (eq(actual,expected)) {
    /* same expected partition as last time */
    printf("success\n");
  }
  else {
    result = 1;
    printf("failed\n");
    goto end;
  }
  freeall(actual);


  /* Now repeat the whole thing for a PERMUTATION (instead of a
   * PARTITION). These are the only two kinds of object that first()
   * will work on. */
  first_permutation(z, expected); /* expected permutation */

  actual = callocobject();
  printf("testing first permutation (unequal args)...");
  first(PERMUTATION, actual, z);
  if (eq(actual,expected)) {
    printf("success\n");
  }
  else {
    result = 1;
    printf("failed\n");
    goto end;
  }
  freeall(actual);

  /* two equal arguments to first() */
  NEW_INTEGER(actual, 7);
  printf("testing first permutation (equal args)...");
  first(PERMUTATION, actual, actual);
  if (eq(actual,expected)) {
    /* same expected permutation as last time */
    printf("success\n");
  }
  else {
    result = 1;
    printf("failed\n");
  }

 end:
  freeall(z);
  freeall(expected);
  freeall(actual);

  return result;
}


/* Check Pascal's identity using the binom() function */
int test_binom(void) {
  int result = 0;

  OP n = callocobject();
  OP n_minus_one = callocobject();
  OP k = callocobject();
  OP k_minus_one = callocobject();
  OP actual_l = callocobject();
  OP actual_r = callocobject();
  OP actual = callocobject();
  OP expected = callocobject();

  /* make sure these are integers so we can use C_I_I in the loop */
  copy_integer(cons_null, n);
  copy_integer(cons_null, n_minus_one);
  copy_integer(cons_null, k);
  copy_integer(cons_null, k_minus_one);

  printf("testing pascal's identity using binom...");
  for (INT N = 1; N <= 100; N++) {
    for (INT K = 1; K <= N; K++) {
      C_I_I(n, N);
      C_I_I(n_minus_one, N-1);
      C_I_I(k, K);
      C_I_I(k_minus_one, K-1);
      binom(n,k,expected);
      binom(n_minus_one, k_minus_one, actual_l);
      binom(n_minus_one, k, actual_r);
      add(actual_l, actual_r, actual);
      if (!eq(actual, expected)) {
	result = 1;
      }
    }
  }
  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(n);
  freeall(n_minus_one);
  freeall(k);
  freeall(k_minus_one);
  freeall(actual_l);
  freeall(actual_r);
  freeall(actual);
  freeall(expected);

  return result;
}


/* Squaring and squareroot should be inverses */
int test_squareroot(void) {
  int result = 0;

  OP a = callocobject();
  OP a_sqrad = callocobject();
  OP a2 = callocobject();
  OP actual = callocobject();

  /* want "a" to be an integer so we can use C_I_I in the loop */
  copy_integer(cons_null, a);

  printf("testing that squareroot is the inverse of squaring...");
  for (INT A=1; A <= 100; A++) {
    C_I_I(a,A);
    mult(a,a,a2);
    squareroot(a2, actual);

    /* Despite what the docs say, squareroot() always returns a sqrad,
     * EXCEPT for the square root of zero, so we have to convert a ->
     * a_sqrad before comparing. */
    make_scalar_sqrad(a, a_sqrad);
    if (!eq(actual, a_sqrad)) {
      result = 1;
    }

    /* The integer square root should be the same as the regular
     * square root since a2 is a perfect square */
    ganzsquareroot(a2, actual);
    if (!eq(a,actual)) {
      result = 1;
    }
  }

  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(a);
  freeall(a_sqrad);
  freeall(a2);
  freeall(actual);

  return result;
}


/* Test inversion (of integers, for now) */
int test_invers(void) {
  int result = 0;

  OP a = callocobject();
  OP a_bruch = callocobject();
  OP a_inv = callocobject();
  OP a_inv_inv = callocobject();
  OP eins_inv = callocobject();

  /* want "a" to be an integer so we can use C_I_I in the loop */
  copy_integer(cons_null, a);

  /* warning: inverting 1 will get you 1, not 1/1 */
  printf("testing integer inversion (n=1)...");
  invers(cons_eins, eins_inv);
  if (!eq(eins_inv, cons_eins)) {
    result = 1;
  }

  printf("testing integer inversion (n>1)...");
  for (INT A=2; A <= 100; A++) {
    C_I_I(a, A);
    invers(a, a_inv);
    invers(a_inv, a_inv_inv);

    if (!eq(s_b_o(a_inv), cons_eins)) {
      /* numerator != 1*/
      result = 1;
    }

    if (!eq(s_b_u(a_inv), a)) {
      /* denominator != a */
      result = 1;
    }

    m_scalar_bruch(a, a_bruch);
    if (!eq(a_inv_inv, a_bruch)) {
      /* a-inverse-inverse != a/1 */
      result = 1;
    }
  }

  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(a);
  freeall(a_bruch);
  freeall(a_inv);
  freeall(a_inv_inv);
  freeall(eins_inv);

  return result;
}


/* Test the Euler phi function */
int test_euler_phi(void) {
  int result = 0;

  OP a = callocobject();
  OP actual = callocobject();
  OP expected = callocobject();

  /* want these to be integers so we can use C_I_I in the loop */
  copy_integer(cons_null, a);
  copy_integer(cons_null, expected);

  printf("testing the euler_phi (totient) function...");
  INT expecteds[] = {1,1,2,2,4,2,6,4,6,4};

  for (INT A=1; A <= 10; A++) {
    C_I_I(a, A);
    C_I_I(expected, expecteds[A-1]);
    euler_phi(a, actual);

    if (!eq(actual, expected)) {
      result = 1;
    }
  }

  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(a);
  freeall(actual);
  freeall(expected);

  return result;
}


/* Test manual object creation */
int test_manual_object_creation(void) {
  int result = 0;

  OP a = callocobject();

  /* Note: ob_INT is declared as an intptr_t, but that's to ensure
   * that it has the same size as the other members of the union,
   * which are all pointers. It's just a regular integer; not a
   * pointer to one. */
  OBJECTSELF d;
  d.ob_INT = 3;

  c_o_k(a, INTEGER);
  c_o_s(a, d);

  printf("testing manual object construction...");
  if (!eq(a, cons_drei)) {
    result = 1;
  }

  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(a);

  return result;
}


/* Create and copy a random word (i.e. an integer vector) */
int test_random_word(void) {
  int result = 0;

  OP a = callocobject();
  OP w = callocobject();
  OP w2 = callocobject();
  m_i_i(10, a); /* how long to make the word */
  random_word(a,w);

  printf("creating and copying a random word...");
  /* the vector itself should be an INTEGERVECTOR */
  if (s_o_k(w) != WORD) {
    result = 1;
  }

  for (INT i = 0; i < 10; i++) {
    /* all components should be integers */
    if (s_o_k(s_v_i(w, i)) != INTEGER) {
      result = 1;
    }
  }

  /* the copied word should be identical (comp_word returns -1,0,1 a
   * la strcmp) */
  copy_word(w,w2);
  if (comp_word(w,w2) != 0) {
    result = 1;
  }

  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(a);
  freeall(w);
  freeall(w2);

  return result;
}


/* Test basic rational arithmetic */
int test_rational_arithmetic(void) {
  int result = 0;

  INT a, b, c, d;
  OP x = callocobject(); /* a/b */
  OP y = callocobject(); /* c/d */
  OP x_plus_y = callocobject();
  OP x_times_y = callocobject();
  OP expected = callocobject();

  printf("adding, multiplying, and reducing random fractions...");
  for (int i=0; i < 100; i++) {
    random_bruch(x);
    random_bruch(y);
    a = s_b_oi(x);
    b = s_b_ui(x);
    c = s_b_oi(y);
    d = s_b_ui(y);

    m_ioiu_b(a*d + b*c, b*d, expected);
    add(x,y,x_plus_y);
    if (!eq(expected, x_plus_y)) {
      result = 1;
    }

    m_ioiu_b(a*c, b*d, expected);
    mult(x,y,x_times_y);
    if (!eq(expected, x_times_y)) {
      result = 1;
    }

    /* Now make a copy of x (which should afterwards be equal to
     * it) */
    copy_bruch(x,y);
    if (!eq(x,y)) {
      result = 1;
    }

    /* ...and reduce the copy to lowest terms; again, it should
     * remain equal to the original fraction. */
    kuerzen(y);
    if (!eq(x,y)) {
      result = 1;
    }

    /* The reduced fraction should be either nonnegative, or negative,
     * right? */
    if (!posp(y) && !negp(y)) {
      result = 1;
    }
  }

  if (result == 0) {
    printf("success\n");
  }
  else {
    printf("failed\n");
  }

  freeall(x);
  freeall(y);
  freeall(x_plus_y);
  freeall(x_times_y);
  freeall(expected);

  return result;
}


int main(int argc, char** argv) {
  int result = 0;
  anfang();

  /* These have yet to be converted to something testable. Most
   * require user input, and simply print the results:
   *
   *   - test_brc (has return value)
   *   - test_dcp (has return value)
   *   - test_kostka
   *   - test_list
   *   - test_longint
   *   - test_matrix
   *   - test_mdg (has return value)
   *   - test_ndg
   *   - test_perm
   *   - test_plet
   *   - test_poly (has return value)
   *   - test_schubert
   *   - test_schur
   *   - test_symchar
   */

  result |= test_fakul(11);
  result |= test_brauer_char();
  result |= test_bintree_insert_copy();
  result |= test_mult_schur_schur();
  result |= test_mult_schur_schur2();
  result |= test_first();
  result |= test_binom();
  result |= test_squareroot();
  result |= test_invers();
  result |= test_euler_phi();
  result |= test_manual_object_creation();
  result |= test_random_word();
  result |= test_rational_arithmetic();

  ende();
  return result;
}
