require 'test/spec' require 'solve' context "Solve" do specify "works for single variables" do v = Solve::Variable.new(:v) r = nil solve(v == 5) { |r| r[:v].should.equal 5 } r.should.be.kind_of Hash end specify "works for &" do u = Solve::Variable.new(:u) v = Solve::Variable.new(:v) r = nil solve((u == 2) & (v == 5)) { |r| r[:u].should.equal 2 r[:v].should.equal 5 } r.should.be.kind_of Hash end specify "works for |" do u = Solve::Variable.new(:u) v = Solve::Variable.new(:v) n = 0 solve((u == 2) | (v == 5)) { |r| n += 1 case n when 1 r[:u].should.equal 2 when 2 r[:v].should.equal 5 end } n.should.be 2 end specify "works for indirect variables" do u = Solve::Variable.new(:u) v = Solve::Variable.new(:v) r = nil solve((u == 5) & (v == u)) { |r| r[:u].should.equal 5 r[:v].should.equal 5 } r.should.be.kind_of Hash end specify "works for multiple &" do a, b, c = Solve.variables :a, :b, :c solve((a == 1) & (b == 2) & (c == a)) { |r| r.should.equal({:a => 1, :b => 2, :c => a}) } end specify "works for multiple |" do a, b, c = Solve.variables :a, :b, :c rs = {} solve((a == 1) | (b == 2) | (c == a)) { |r| rs.update r } rs.should.equal({:a => 1, :b => 2, :c => a}) end specify "works for mixed | and &" do a, b, c = Solve.variables :a, :b, :c solve((a == 1) & (b == 2) & ((c == a) | (c == b))).should.equal \ [{:a=>1, :b=>2, :c=>1}, {:a=>1, :b=>2, :c=>2}] end specify "works for ranges" do a = Solve::Variable.new :a solve(a.oneof(1..4)).should.equal [{:a => 1},{:a => 2},{:a => 3},{:a => 4}] end specify "works with negation" do a = Solve::Variable.new :a solve(a.oneof(1..4) & ~(a == 2)).should.equal [{:a => 1},{:a => 3},{:a => 4}] end end