Acme-ExtUtils-XSOne-Test-Calculator
view release on metacpan or search on metacpan
t/01-calculator.t view on Meta::CPAN
is(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::safe_sqrt(16), 4, 'safe_sqrt(16) = 4');
is(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::safe_sqrt(-1), 0, 'safe_sqrt(-1) = 0 (no croak)');
is(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::combination(5, 2), 10, 'combination(5, 2) = 10');
is(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::permutation(5, 2), 20, 'permutation(5, 2) = 20');
};
subtest 'Logarithms' => sub {
plan tests => 6;
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::log_natural(exp(1)) - 1) < 0.0001, 'ln(e) = 1');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::log10_val(100) - 2) < 0.0001, 'log10(100) = 2');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::log_base(8, 2) - 3) < 0.0001, 'log2(8) = 3');
is(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::nth_root(27, 3), 3, 'nth_root(27, 3) = 3');
# Test C helper function (defined in scientific.xs preamble)
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::safe_log(exp(1)) - 1) < 0.0001, 'safe_log(e) = 1');
is(Acme::ExtUtils::XSOne::Test::Calculator::Scientific::safe_log(-1), 0, 'safe_log(-1) = 0 (no croak)');
};
subtest 'Scientific error handling' => sub {
plan tests => 3;
eval { Acme::ExtUtils::XSOne::Test::Calculator::Scientific::sqrt_val(-1) };
like($@, qr/negative/, 'sqrt of negative croaks');
eval { Acme::ExtUtils::XSOne::Test::Calculator::Scientific::log_natural(-1) };
like($@, qr/non-positive/, 'log of negative croaks');
eval { Acme::ExtUtils::XSOne::Test::Calculator::Scientific::factorial(-1) };
like($@, qr/negative/, 'factorial of negative croaks');
};
# =============================================================================
# Test Trig operations
# =============================================================================
subtest 'Trigonometric functions' => sub {
plan tests => 14;
my $pi = Acme::ExtUtils::XSOne::Test::Calculator::pi();
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::sin_val(0)) < 0.0001, 'sin(0) = 0');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::sin_val($pi/2) - 1) < 0.0001, 'sin(pi/2) = 1');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::cos_val(0) - 1) < 0.0001, 'cos(0) = 1');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::cos_val($pi) - (-1)) < 0.0001, 'cos(pi) = -1');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::tan_val(0)) < 0.0001, 'tan(0) = 0');
is(Acme::ExtUtils::XSOne::Test::Calculator::Trig::hypot_val(3, 4), 5, 'hypot(3, 4) = 5');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::deg_to_rad(180) - $pi) < 0.0001, 'deg_to_rad(180) = pi');
# Test C helper functions (defined in trig.xs preamble)
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::normalize_angle(3 * $pi) - $pi) < 0.0001, 'normalize_angle(3*pi) = pi');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::normalize_angle(-3 * $pi) - (-$pi)) < 0.0001, 'normalize_angle(-3*pi) = -pi');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::sec_val(0) - 1) < 0.0001, 'sec(0) = 1');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::csc_val($pi/2) - 1) < 0.0001, 'csc(pi/2) = 1');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::cot_val($pi/4) - 1) < 0.0001, 'cot(pi/4) = 1');
is(Acme::ExtUtils::XSOne::Test::Calculator::Trig::is_valid_asin_arg(0.5), 1, 'is_valid_asin_arg(0.5) = 1');
is(Acme::ExtUtils::XSOne::Test::Calculator::Trig::is_valid_asin_arg(2.0), 0, 'is_valid_asin_arg(2.0) = 0');
};
subtest 'Inverse trig' => sub {
plan tests => 3;
my $pi = Acme::ExtUtils::XSOne::Test::Calculator::pi();
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::asin_val(1) - $pi/2) < 0.0001, 'asin(1) = pi/2');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::acos_val(0) - $pi/2) < 0.0001, 'acos(0) = pi/2');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::atan_val(1) - $pi/4) < 0.0001, 'atan(1) = pi/4');
};
# =============================================================================
# Test Memory - THIS IS THE KEY TEST FOR SHARED STATE!
# =============================================================================
subtest 'Memory operations' => sub {
plan tests => 13;
Acme::ExtUtils::XSOne::Test::Calculator::Memory::clear();
ok(Acme::ExtUtils::XSOne::Test::Calculator::Memory::store(0, 42), 'store(0, 42) succeeds');
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::recall(0), 42, 'recall(0) = 42');
ok(Acme::ExtUtils::XSOne::Test::Calculator::Memory::store(5, 3.14), 'store(5, 3.14) succeeds');
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::recall(5), 3.14, 'recall(5) = 3.14');
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::max_memory_slots(), 10, 'max_memory_slots = 10');
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::max_history_entries(), 100, 'max_history_entries = 100');
# Test C helper functions (defined in _header.xs, exposed via memory.xs)
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::is_valid_slot(5), 1, 'is_valid_slot(5) = 1');
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::is_valid_slot(-1), 0, 'is_valid_slot(-1) = 0');
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::is_valid_slot(10), 0, 'is_valid_slot(10) = 0');
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::used_slots(), 2, 'used_slots() = 2 (slots 0 and 5)');
ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Memory::sum_all_slots() - (42 + 3.14)) < 0.0001, 'sum_all_slots() = 45.14');
Acme::ExtUtils::XSOne::Test::Calculator::Memory::add_to(0, 8);
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::recall(0), 50, 'add_to(0, 8) makes slot 0 = 50');
Acme::ExtUtils::XSOne::Test::Calculator::Memory::add_to(1, 100);
is(Acme::ExtUtils::XSOne::Test::Calculator::Memory::recall(1), 100, 'add_to empty slot sets value');
};
subtest 'Shared state - ans() tracks last result' => sub {
plan tests => 5;
# This test proves that all modules share the same C static variables
Acme::ExtUtils::XSOne::Test::Calculator::Memory::clear();
# Do a calculation in Basic
my $result1 = Acme::ExtUtils::XSOne::Test::Calculator::Basic::add(10, 20);
is($result1, 30, 'add(10, 20) = 30');
( run in 0.989 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )