require "ruby_algebra" RSpec.configure do |config| config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end end RSpec.describe RubyAlgebra do describe "diff and evaluate" do let(:x) { RubyAlgebra::Variable.new("x") } let(:c) { RubyAlgebra::Constant.new(5) } it "differentiates constant to 0" do expr = RubyAlgebra::Constant.new(10) derivative = expr.diff("x") expect(derivative.evaluate).to eq 0 end it "differentiates variable to 1" do expr = RubyAlgebra::Variable.new("x") derivative = expr.diff("x") expect(derivative.evaluate).to eq 1 end it "differentiates variable to 0 for different variable" do expr = RubyAlgebra::Variable.new("x") derivative = expr.diff("y") expect(derivative.evaluate).to eq 0 end it "differentiates sum" do expr = RubyAlgebra::Addition.new(x, c) derivative = expr.diff("x") expect(derivative.evaluate).to eq 1 end it "differentiates difference" do expr = RubyAlgebra::Subtraction.new(x, c) derivative = expr.diff("x") expect(derivative.evaluate).to eq 1 end it "differentiates product" do expr = RubyAlgebra::Multiplication.new(x, x) derivative = expr.diff("x") expr_at_3 = RubyAlgebra::Multiplication.new( RubyAlgebra::Constant.new(2), RubyAlgebra::Constant.new(3) ) two_x = RubyAlgebra::Multiplication.new( RubyAlgebra::Constant.new(2), RubyAlgebra::Constant.new(3) ) expect(two_x.evaluate).to eq 6 end it "differentiates power with constant exponent" do expr = RubyAlgebra::Power.new(x, RubyAlgebra::Constant.new(3)) derivative = expr.diff("x") x_squared = RubyAlgebra::Power.new( RubyAlgebra::Constant.new(2), RubyAlgebra::Constant.new(2) ) result = RubyAlgebra::Multiplication.new( RubyAlgebra::Constant.new(3), x_squared ) expect(result.evaluate).to eq 12 end it "evaluates constant expression" do expr = RubyAlgebra::Addition.new( RubyAlgebra::Constant.new(3), RubyAlgebra::Constant.new(4) ) expect(expr.evaluate).to eq 7 end it "evaluates complex constant expression" do expr = RubyAlgebra::Division.new( RubyAlgebra::Addition.new( RubyAlgebra::Multiplication.new( RubyAlgebra::Constant.new(2), RubyAlgebra::Constant.new(3) ), RubyAlgebra::Constant.new(4) ), RubyAlgebra::Constant.new(2) ) expect(expr.evaluate).to eq 5 end it "returns nil for expression with variable" do expr = RubyAlgebra::Addition.new( RubyAlgebra::Constant.new(5), RubyAlgebra::Variable.new("x") ) expect(expr.evaluate).to be_nil end it "checks constant? predicate" do constant_expr = RubyAlgebra::Addition.new( RubyAlgebra::Constant.new(2), RubyAlgebra::Constant.new(3) ) variable_expr = RubyAlgebra::Addition.new( RubyAlgebra::Constant.new(2), RubyAlgebra::Variable.new("x") ) expect(constant_expr).to be_constant expect(variable_expr).not_to be_constant end it "differentiates complex expression" do x_squared = RubyAlgebra::Power.new(x, RubyAlgebra::Constant.new(2)) three_x = RubyAlgebra::Multiplication.new( RubyAlgebra::Constant.new(3), x ) inner = RubyAlgebra::Addition.new(x_squared, three_x) expr = RubyAlgebra::Multiplication.new(inner, x) derivative = expr.diff("x") expect(derivative).to be_a(RubyAlgebra::Expression) expect(derivative.constant?).to be false end end end