Загрузка данных


// test_FormulaCalculator.cpp
#include "FormulaCalculator.h"
#include <QDebug>
#include <cassert>
#include <iostream>

// Тесты для проверки семантики копирования/перемещения
void testCopyAndMoveSemantics() {
    std::cout << "Testing copy/move semantics...\n";
    
    FormulaCalculator calc1;
    calc1.setVariable("x", 10.0);
    calc1.setVariable("y", 20.0);
    
    // Тест перемещения
    FormulaCalculator calc2 = std::move(calc1);
    assert(calc2.hasVariable("x"));
    assert(calc2.getVariable("x") == 10.0);
    
    // Тест присваивания с перемещением
    FormulaCalculator calc3;
    calc3 = std::move(calc2);
    assert(calc3.hasVariable("x"));
    assert(calc3.getVariable("x") == 10.0);
    
    std::cout << "Copy/move semantics tests passed!\n";
}

// Тесты лексического анализа
void testLexicalAnalysis() {
    std::cout << "Testing lexical analysis...\n";
    
    FormulaCalculator calc;
    
    // Тест чисел
    assert(calc.isNumber("123"));
    assert(calc.isNumber("3.14"));
    assert(calc.isNumber("-5"));
    assert(!calc.isNumber("abc"));
    
    // Тест переменных
    assert(calc.isVariable("x"));
    assert(calc.isVariable("var123"));
    assert(calc.isVariable("_test"));
    assert(!calc.isVariable("123var"));
    
    // Тест функций
    assert(calc.isFunction("sin"));
    assert(calc.isFunction("cos"));
    assert(calc.isFunction("sqrt"));
    assert(!calc.isFunction("unknown"));
    
    // Тест операторов
    assert(calc.isOperator("+"));
    assert(calc.isOperator("-"));
    assert(calc.isOperator("*"));
    assert(calc.isOperator("/"));
    
    std::cout << "Lexical analysis tests passed!\n";
}

// Тесты вычислений
void testCalculations() {
    std::cout << "Testing calculations...\n";
    
    FormulaCalculator calc;
    
    // Простые арифметические операции
    CalculationResult result = calc.parseAndCalculate("2+3");
    assert(result.getValue() == 5.0);
    
    result = calc.parseAndCalculate("10-4");
    assert(result.getValue() == 6.0);
    
    result = calc.parseAndCalculate("3*4");
    assert(result.getValue() == 12.0);
    
    result = calc.parseAndCalculate("15/3");
    assert(result.getValue() == 5.0);
    
    result = calc.parseAndCalculate("2^3");
    assert(result.getValue() == 8.0);
    
    // Сложные выражения
    result = calc.parseAndCalculate("2+3*4");
    assert(result.getValue() == 14.0);
    
    result = calc.parseAndCalculate("(2+3)*4");
    assert(result.getValue() == 20.0);
    
    result = calc.parseAndCalculate("10/2+3");
    assert(result.getValue() == 8.0);
    
    std::cout << "Calculations tests passed!\n";
}

// Тесты функций
void testFunctions() {
    std::cout << "Testing functions...\n";
    
    FormulaCalculator calc;
    
    CalculationResult result = calc.parseAndCalculate("sin(0)");
    assert(fabs(result.getValue() - 0.0) < 1e-10);
    
    result = calc.parseAndCalculate("cos(0)");
    assert(fabs(result.getValue() - 1.0) < 1e-10);
    
    result = calc.parseAndCalculate("sqrt(16)");
    assert(result.getValue() == 4.0);
    
    result = calc.parseAndCalculate("exp(1)");
    assert(fabs(result.getValue() - 2.718281828459045) < 1e-10);
    
    result = calc.parseAndCalculate("log(100)");
    assert(fabs(result.getValue() - 4.605170185988092) < 1e-10);
    
    std::cout << "Functions tests passed!\n";
}

// Тесты переменных
void testVariables() {
    std::cout << "Testing variables...\n";
    
    FormulaCalculator calc;
    
    calc.setVariable("x", 10.0);
    calc.setVariable("y", 20.0);
    
    CalculationResult result = calc.parseAndCalculate("x+y");
    assert(result.getValue() == 30.0);
    
    result = calc.parseAndCalculate("x*y");
    assert(result.getValue() == 200.0);
    
    result = calc.parseAndCalculate("sin(x)");
    assert(fabs(result.getValue() - sin(10.0)) < 1e-10);
    
    assert(calc.hasVariable("x"));
    assert(!calc.hasVariable("z"));
    
    auto vars = calc.getAllVariables();
    assert(vars.size() == 2);
    assert(vars["x"] == 10.0);
    
    calc.clearVariables();
    assert(!calc.hasVariable("x"));
    
    std::cout << "Variables tests passed!\n";
}

// Тесты команд
void testCommands() {
    std::cout << "Testing commands...\n";
    
    FormulaCalculator calc;
    calc.setVariable("x", 5.0);
    
    // Проверка команды clear
    CalculationResult result = calc.parseAndCalculate("x clear");
    assert(!calc.hasVariable("x"));
    
    calc.setVariable("y", 10.0);
    result = calc.parseAndCalculate("y+y table");
    assert(result.hasTable());
    
    std::cout << "Commands tests passed!\n";
}

// Тесты обработки ошибок
void testErrorHandling() {
    std::cout << "Testing error handling...\n";
    
    FormulaCalculator calc;
    
    // Деление на ноль
    CalculationResult result = calc.parseAndCalculate("5/0");
    // Должно быть обработано через исключение
    
    // Неопределенная переменная
    result = calc.parseAndCalculate("a+b");
    // Должна быть ошибка
    
    // Неправильный синтаксис
    result = calc.parseAndCalculate("2++3");
    
    // Непарные скобки
    result = calc.parseAndCalculate("(2+3");
    
    std::cout << "Error handling tests passed!\n";
}

// Тест перегрузки операторов и семантики
void testOperatorOverloads() {
    std::cout << "Testing operator overloads and semantics...\n";
    
    FormulaCalculator calc1;
    calc1.setVariable("test", 100.0);
    
    // Тест перемещения
    FormulaCalculator calc2(std::move(calc1));
    assert(calc2.hasVariable("test"));
    assert(calc2.getVariable("test") == 100.0);
    
    // Тест присваивания
    FormulaCalculator calc3;
    calc3 = std::move(calc2);
    assert(calc3.hasVariable("test"));
    
    std::cout << "Operator overloads tests passed!\n";
}

// Главная функция тестирования
void runAllTests() {
    std::cout << "\n=== Starting TDD Tests ===\n\n";
    
    testCopyAndMoveSemantics();
    testLexicalAnalysis();
    testCalculations();
    testFunctions();
    testVariables();
    testCommands();
    testErrorHandling();
    testOperatorOverloads();
    
    std::cout << "\n=== All tests passed successfully! ===\n\n";
}