require_relative "helper" class User < Ohm::Model attribute :email attribute :update attribute :activation_code attribute :sandunga index :email index :email_provider index :working_days index :update index :activation_code def working_days @working_days ||= [] end def email_provider email.split("@").last end def before_save self.activation_code ||= "user:#{id}" end end setup do @user1 = User.create(:email => "foo", :activation_code => "bar", :update => "baz") @user2 = User.create(:email => "bar") @user3 = User.create(:email => "baz qux") end test "be able to find by the given attribute" do assert @user1 == User.find(:email => "foo").first end test "raise if the index doesn't exist" do assert_raise Ohm::IndexNotFound do User.find(:address => "foo") end end test "raise an error if the parameter supplied is not a hash" do begin User.find(1) rescue => ex ensure assert ex.kind_of?(ArgumentError) assert ex.message == "You need to supply a hash with filters. If you want to find by ID, use User[id] instead." end end test "avoid intersections with the all collection" do assert_equal "User:indices:email:foo", User.find(:email => "foo").key end test "allow multiple chained finds" do assert 1 == User.find(:email => "foo").find(:activation_code => "bar").find(:update => "baz").size end test "return nil if no results are found" do assert User.find(:email => "foobar").empty? assert nil == User.find(:email => "foobar").first end test "update indices when changing attribute values" do @user1.email = "baz" @user1.save assert [] == User.find(:email => "foo").to_a assert [@user1] == User.find(:email => "baz").to_a end test "remove from the index after deleting" do @user2.delete assert [] == User.find(:email => "bar").to_a end test "work with attributes that contain spaces" do assert [@user3] == User.find(:email => "baz qux").to_a end # Indexing arbitrary attributes setup do @user1 = User.create(:email => "foo@gmail.com") @user2 = User.create(:email => "bar@gmail.com") @user3 = User.create(:email => "bazqux@yahoo.com") end test "allow indexing by an arbitrary attribute" do gmail = User.find(:email_provider => "gmail.com").to_a assert [@user1, @user2] == gmail.sort_by { |u| u.id } assert [@user3] == User.find(:email_provider => "yahoo.com").to_a end scope do # Just to give more context around this bug, basically it happens # when you define a virtual unique or index. # # Previously it was unable to cleanup the indices mainly because # it relied on the attributes being set. class Node < Ohm::Model index :available attribute :capacity unique :available def available capacity.to_i <= 90 end end test "index bug" do n = Node.create n.update(capacity: 91) assert_equal 0, Node.find(available: true).size end test "uniques bug" do n = Node.create n.update(capacity: 91) assert_equal nil, Node.with(:available, true) end end