Blame view

emulateur/epsilon-nofrendo/poincare/test/helper.cpp 5.96 KB
6663b6c9   adorian   projet complet av...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
  #include <quiz.h>
  #include <poincare.h>
  #include <string.h>
  #include <ion.h>
  #include <stdlib.h>
  #include <assert.h>
  #include <cmath>
  #include "helper.h"
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
  #include "../src/expression_debug.h"
  #include <iostream>
  using namespace std;
  #endif
  
  using namespace Poincare;
  
  void translate_in_special_chars(char * expression) {
    for (char *c = expression; *c; c++) {
      switch (*c) {
        case 'E': *c = Ion::Charset::Exponent; break;
        case 'X': *c = Ion::Charset::Exponential; break;
        case 'I': *c = Ion::Charset::IComplex; break;
        case 'R': *c = Ion::Charset::Root; break;
        case 'P': *c = Ion::Charset::SmallPi; break;
        case '*': *c = Ion::Charset::MultiplicationSign; break;
        case '>': *c = Ion::Charset::Sto; break;
      }
    }
  }
  
  void translate_in_ASCII_chars(char * expression) {
    for (char *c = expression; *c; c++) {
      switch (*c) {
        case Ion::Charset::Exponent: *c = 'E'; break;
        case Ion::Charset::Exponential: *c = 'X'; break;
        case Ion::Charset::IComplex: *c = 'I'; break;
        case Ion::Charset::Root: *c = 'R'; break;
        case Ion::Charset::SmallPi: *c = 'P'; break;
        case Ion::Charset::MultiplicationSign: *c = '*'; break;
        case Ion::Charset::MiddleDot: *c = '*'; break;
        case Ion::Charset::Sto: *c = '>'; break;
      }
    }
  }
  
  Expression * parse_expression(const char * expression) {
    quiz_print(expression);
    char buffer[200];
    strlcpy(buffer, expression, sizeof(buffer));
    translate_in_special_chars(buffer);
    Expression * result = Expression::parse(buffer);
    assert(result);
    return result;
  }
  
  void assert_parsed_expression_type(const char * expression, Poincare::Expression::Type type) {
    Expression * e = parse_expression(expression);
    assert(e->type() == type);
    delete e;
  }
  
  void assert_parsed_expression_polynomial_degree(const char * expression, int degree, char symbolName) {
    GlobalContext globalContext;
    Expression * e = parse_expression(expression);
    Expression::Simplify(&e, globalContext, Radian);
    assert(e->polynomialDegree(symbolName) == degree);
    delete e;
  }
  
  typedef Expression * (*ProcessExpression)(Expression *, Context & context, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat);
  
  void assert_parsed_expression_process_to(const char * expression, const char * result, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat, ProcessExpression process, int numberOfSignifiantDigits = PrintFloat::k_numberOfStoredSignificantDigits) {
    GlobalContext globalContext;
    Expression * e = parse_expression(expression);
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
    cout << " Entry expression: " << expression << "----"  << endl;
  #endif
    Expression::Simplify(&e, globalContext, angleUnit);
    Expression * m = process(e, globalContext, angleUnit, complexFormat);
    char buffer[500];
    m->writeTextInBuffer(buffer, sizeof(buffer), DecimalMode, numberOfSignifiantDigits);
    translate_in_ASCII_chars(buffer);
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
    print_expression(e, 0);
    cout << "---- serialize to: " << buffer << " ----"  << endl;
    cout << "----- compared to: " << result << " ----\n"  << endl;
  #endif
    assert(strcmp(buffer, result) == 0);
    delete e;
    if (e != m) {
      delete m;
    }
  }
  
  template<typename T>
  void assert_parsed_expression_evaluates_to(const char * expression, const char * approximation, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat, int numberOfSignificantDigits) {
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
    cout << "--------- Approximation ---------" << endl;
  #endif
    int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits;
    numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits;
    assert_parsed_expression_process_to(expression, approximation, angleUnit, complexFormat, [](Expression * e, Context & context, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat) {
          return e->approximate<T>(context, angleUnit, complexFormat);
        }, numberOfDigits);
  }
  
  void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Expression::AngleUnit angleUnit) {
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
    cout << "--------- Simplification ---------" << endl;
  #endif
    assert_parsed_expression_process_to(expression, simplifiedExpression, angleUnit, Expression::ComplexFormat::Cartesian, [](Expression * e, Context & context, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat) { return e; });
  }
  
  void assert_parsed_expression_layout_serialize_to_self(const char * expressionLayout) {
    Expression * e = parse_expression(expressionLayout);
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
    cout << "---- Serialize: " << expressionLayout << "----"  << endl;
  #endif
    ExpressionLayout * el = e->createLayout(DecimalMode, PrintFloat::k_numberOfStoredSignificantDigits);
    int bufferSize = 255;
    char buffer[bufferSize];
    el->writeTextInBuffer(buffer, bufferSize);
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
    cout << "---- serialized to: " << buffer << " ----\n"  << endl;
  #endif
    assert(strcmp(expressionLayout, buffer) == 0);
    delete e;
    delete el;
  }
  
  void assert_expression_layout_serialize_to(Poincare::ExpressionLayout * layout, const char * serialization) {
    int bufferSize = 255;
    char buffer[bufferSize];
    layout->writeTextInBuffer(buffer, bufferSize);
  #if POINCARE_TESTS_PRINT_EXPRESSIONS
    cout << "---- Serialize: " << serialization << "----"  << endl;
    cout << "---- serialized to: " << buffer << " ----"  << endl;
    cout << "----- compared to: " << serialization << " ----\n"  << endl;
  #endif
    assert(strcmp(serialization, buffer) == 0);
  }
  
  template void assert_parsed_expression_evaluates_to<float>(char const*, char const *, Poincare::Expression::AngleUnit, Poincare::Expression::ComplexFormat, int);
  template void assert_parsed_expression_evaluates_to<double>(char const*, char const *, Poincare::Expression::AngleUnit, Poincare::Expression::ComplexFormat, int);