require 'spec_helper'

describe Score do

  LOCA = 1234
  ADDRA = 0x01020304
  NODEA = 'anodeid'

  LOCB = 2345
  ADDRB = 0x02030405
  NODEB = 'bnodeid'

  LOCC = 3456
  ADDRC = 0x03040506
  NODEC = 'cnodeid'

  LOCD = 4567
  ADDRD = 0x04050607
  NODED = 'dnodeid'

  LOCE = 5678
  ADDRE = 0x05060708
  NODEE = 'enodeid'

  LOCF = 6789
  ADDRF = 0x06070809
  NODEF = 'fnodeid'

  let(:user1) { FactoryGirl.create(:user, last_jam_locidispid: LOCA, last_jam_audio_latency: 13) }
  let(:user2) { FactoryGirl.create(:user, last_jam_locidispid: LOCB, last_jam_audio_latency: 17) }

  let(:score_with_user)          { s1, s2 = Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil, 'foo', { auserid: user1.id, buserid: user2.id }); s1 }
  let(:score_with_user_reversed) { s1, s2 = Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil, 'foo', { auserid: user2.id, buserid: user1.id }); s1 }

  let(:latency_tester1) { FactoryGirl.create(:latency_tester) }
  let(:latency_tester2) { FactoryGirl.create(:latency_tester) }

  let(:score_with_latency_tester) { s1, s2 = Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil, 'foo', { alatencytestid: latency_tester1.id, blatencytestid: latency_tester2.id}); s1 }

  describe "with default scores" do
    before do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil, 'foo')
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 30, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 40, Time.new.utc-3600, 'foo')
    end

    it "count" do
      Score.count.should == 6
    end

    it 'a to b' do
      s = Score.where(alocidispid: LOCA, blocidispid: LOCB).limit(1).first
      s.should_not be_nil
      s.alocidispid.should == LOCA
      s.anodeid.should eql(NODEA)
      s.aaddr.should == ADDRA
      s.blocidispid.should == LOCB
      s.bnodeid.should eql(NODEB)
      s.baddr.should == ADDRB
      s.score.should == 20
      s.scorer.should == 0
      s.score_dt.should_not be_nil
      s.scoring_data.should eq('foo')
    end

    it 'b to a' do
      s = Score.where(alocidispid: LOCB, blocidispid: LOCA).limit(1).first
      s.should_not be_nil
      s.alocidispid.should == LOCB
      s.anodeid.should eql(NODEB)
      s.aaddr.should == ADDRB
      s.blocidispid.should == LOCA
      s.bnodeid.should eql(NODEA)
      s.baddr.should == ADDRA
      s.score.should == 20
      s.scorer.should == 1
      s.score_dt.should_not be_nil
      s.scoring_data.should be_nil
    end

    it 'a to c' do
      s = Score.where(alocidispid: LOCA, blocidispid: LOCC).limit(1).first
      s.should_not be_nil
      s.alocidispid.should == LOCA
      s.anodeid.should eql(NODEA)
      s.aaddr.should == ADDRA
      s.blocidispid.should == LOCC
      s.bnodeid.should eql(NODEC)
      s.baddr.should == ADDRC
      s.score.should == 30
      s.scorer.should == 0
      s.score_dt.should_not be_nil
      s.scoring_data.should be_nil
    end

    it 'c to a' do
      s = Score.where(alocidispid: LOCC, blocidispid: LOCA).limit(1).first
      s.should_not be_nil
      s.alocidispid.should == LOCC
      s.anodeid.should eql(NODEC)
      s.aaddr.should == ADDRC
      s.blocidispid.should == LOCA
      s.bnodeid.should eql(NODEA)
      s.baddr.should == ADDRA
      s.score.should == 30
      s.scorer.should == 1
      s.score_dt.should_not be_nil
      s.scoring_data.should be_nil
    end

    it 'delete a to c' do
      Score.deletex(LOCA, LOCC)
      Score.count.should == 2
      Score.where(alocidispid: LOCA, blocidispid: LOCC).limit(1).first.should be_nil
      Score.where(alocidispid: LOCC, blocidispid: LOCA).limit(1).first.should be_nil
      Score.where(alocidispid: LOCA, blocidispid: LOCB).limit(1).first.should_not be_nil
      Score.where(alocidispid: LOCB, blocidispid: LOCA).limit(1).first.should_not be_nil
    end

    it 'findx' do
      Score.findx(LOCA, LOCA).should == -1
      Score.findx(LOCA, LOCB).should == 20
      Score.findx(LOCA, LOCC).should == 30

      Score.findx(LOCB, LOCA).should == 20
      Score.findx(LOCB, LOCB).should == -1
      Score.findx(LOCB, LOCC).should == -1

      Score.findx(LOCC, LOCA).should == 30
      Score.findx(LOCC, LOCB).should == -1
      Score.findx(LOCC, LOCC).should == -1
    end

    it "test shortcut for making scores from connections" do
      user1 = FactoryGirl.create(:user)
      conn1 = FactoryGirl.create(:connection, user: user1, addr: ADDRD, locidispid: LOCD)
      user2 = FactoryGirl.create(:user)
      conn2 = FactoryGirl.create(:connection, user: user2, addr: ADDRE, locidispid: LOCE)
      user3 = FactoryGirl.create(:user)
      conn3 = FactoryGirl.create(:connection, user: user3, addr: ADDRF, locidispid: LOCF)

      Score.findx(LOCD, LOCE).should == -1
      Score.findx(LOCE, LOCD).should == -1
      Score.findx(LOCD, LOCF).should == -1
      Score.findx(LOCF, LOCD).should == -1
      Score.findx(LOCE, LOCF).should == -1
      Score.findx(LOCF, LOCE).should == -1

      Score.score_conns(conn1, conn2, 12)
      Score.score_conns(conn1, conn3, 13)
      Score.score_conns(conn2, conn3, 23)

      Score.findx(LOCD, LOCE).should == 12
      Score.findx(LOCE, LOCD).should == 12
      Score.findx(LOCD, LOCF).should == 13
      Score.findx(LOCF, LOCD).should == 13
      Score.findx(LOCE, LOCF).should == 23
      Score.findx(LOCF, LOCE).should == 23
    end

    describe "createx" do
      it "creates with user info" do
        score_with_user.touch
        score_with_user.auserid.should == user1.id
        score_with_user.buserid.should == user2.id
        score_with_user.alatencytestid.should be_nil
        score_with_user.blatencytestid.should be_nil
      end

      it "creates with latency-tester info" do
        score_with_latency_tester.touch
        score_with_latency_tester.auserid.should be_nil
        score_with_latency_tester.buserid.should be_nil
        score_with_latency_tester.alatencytestid.should == latency_tester1.id
        score_with_latency_tester.blatencytestid.should == latency_tester2.id
      end
    end
  end

  # current_network_scores is a view that tries to take the median of up to the last 5 entries
  describe "current_network_scores" do
    it "works with empty data set" do
      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 0
    end

    it "works with one score" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY alocidispid')
      result.check
      result.ntuples.should == 2
      result[0]['alocidispid'].to_i.should == LOCA
      result[0]['blocidispid'].to_i.should == LOCB
      result[0]['score'].to_i.should == 20
      result[1]['alocidispid'].to_i.should == LOCB
      result[1]['blocidispid'].to_i.should == LOCA
      result[1]['score'].to_i.should == 20
    end

    it "works with two scores in same location" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
      # average of older scores is 20, min = 16, max = 24
      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 24
      result[1]['score'].to_i.should == 24
    end

    it "works with three scores in same location ascending" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)

      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 26
      result[1]['score'].to_i.should == 26
    end

    it "works with three scores in same location descending" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      # average of older scores is 27, min = 21, max = 32

      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 21
      result[1]['score'].to_i.should == 21
    end

    it "works with three scores in same location limited to max" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 90, nil)
      # average of older scores is 22, min = 17, max = 26

      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 26
      result[1]['score'].to_i.should == 26
    end

    it "works with three scores in same location limited to min" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 90, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      # average of older scores is 57, min = 45, max = 68

      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 45
      result[1]['score'].to_i.should == 45
    end

    it "works with more than 5 scores in same location" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 1, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 12, nil)
      # this will be limited to 80% of the average of the older 5 scores
      # (40+40+40+40+40)/5 = 40, min = 32, max = 48

      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 32
      result[1]['score'].to_i.should == 32

      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 12, nil) # this will be limited to 80% of the average of the latest 5 scores
      # (40+40+40+40+12)/5 = 34, min = 27, max = 40

      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 27
      result[1]['score'].to_i.should == 27

      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 12, nil) # this will be limited to 80% of the average of the latest 5 scores
      # (40+40+40+12+12)/5 = 28, min = 22, max = 33

      result = Score.connection.execute('SELECT * FROM current_network_scores')
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 22
      result[1]['score'].to_i.should == 22
    end

    it "works with one score each in different locations" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)

      result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
      result.check
      result.ntuples.should == 4

      result[0]['score'].to_i.should == 20
      result[1]['score'].to_i.should == 20
      result[2]['score'].to_i.should == 25
      result[3]['score'].to_i.should == 25
    end

    it "works with multiple scores in different locations" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 35, nil)
      # average of older scores is 20 for A/B, 25 for A/C, max = 24 for A/B, 30 for A/C

      result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
      result.check
      result.ntuples.should == 4

      result[0]['score'].to_i.should == 24
      result[1]['score'].to_i.should == 24
      result[2]['score'].to_i.should == 30
      result[3]['score'].to_i.should == 30
    end

    it "works with multiple scores in different locations" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 35, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 45, nil)
      # average of A/B scores is (20+30)/2 = 25, so min = 20, max = 30
      # average of A/C scores is (25+35)/2 = 30, so min = 24, max = 36

      result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
      result.check
      result.ntuples.should == 4

      result[0]['score'].to_i.should == 30
      result[1]['score'].to_i.should == 30
      result[2]['score'].to_i.should == 36
      result[3]['score'].to_i.should == 36
    end

    it "works with over 6 scores in different locations" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 10, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 15, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 35, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 45, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 50, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 55, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 60, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 65, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 70, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 75, nil)
      # average of A/B scores is (20+30+40+50+60)/5 = 40, so min = 32, max = 48
      # average of A/C scores is (25+35+45+55+65)/5 = 45, so min = 36, max = 54

      result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
      result.check
      result.ntuples.should == 4

      result[0]['score'].to_i.should == 48 # 70, but limited to max (48)
      result[1]['score'].to_i.should == 48
      result[2]['score'].to_i.should == 54 # 75, but limited to max (54)
      result[3]['score'].to_i.should == 54

      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 80, nil)
      Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 85, nil)
      # average of A/B scores is (30+40+50+60+70)/5 = 50, so min = 40, max = 60
      # average of A/C scores is (35+45+55+65+75)/5 = 55, so min = 44, max = 66

      result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
      result.check
      result.ntuples.should == 4

      result[0]['score'].to_i.should == 60 # 80, but limited to max (60)
      result[1]['score'].to_i.should == 60
      result[2]['score'].to_i.should == 66 # 85, but limited to max (66)
      result[3]['score'].to_i.should == 66
    end

    it "resolves user information with a score created for different users" do
      #pending "i have no idea what this is attempting to demonstrate"

      score_with_user.touch
      score_with_user_reversed.touch

      5.times do
        Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
        Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
      end

      # in the end, since the two scores are so close to each other, the last one will trump
      # (that is, A to B and B to A are both 22).

      result = Score.connection.execute('SELECT * FROM current_network_scores') # where scorer = 0 removed
      result.check
      result.ntuples.should == 2
      result[0]['score'].to_i.should == 22
      result[1]['score'].to_i.should == 22

      result = Score.connection.execute('SELECT * FROM current_scores') # where scorer = 0 removed
      result.check
      result.ntuples.should == 2

      # print "current_scores[0] #{result[0].to_s}\n"
      # print "current_scores[1] #{result[0].to_s}\n"

      if result[0]['a_userid'] == user1.id
        compare_current_score(result[0], user1, user2, 22)
        compare_current_score(result[1], user2, user1, 22)
      else
        compare_current_score(result[0], user2, user1, 22)
        compare_current_score(result[1], user1, user2, 22)
      end

      # create two new users, in the same locations as user1 and user2, but with lower audio gear latency.
      user3 = FactoryGirl.create(:user, last_jam_locidispid: user1.last_jam_locidispid, last_jam_audio_latency: 9)
      user4 = FactoryGirl.create(:user, last_jam_locidispid: user2.last_jam_locidispid, last_jam_audio_latency: 15)

      result = Score.connection.execute('SELECT * FROM current_scores') # where scorer = 0 removed
      result.check
      result.ntuples.should == 8

      # with this data:
      # user1 has a score with user2 and user4.
      # user3 has a score with user2 and user4.
      # so there are these combinations:
      # user1, user2
      # user1, user4
      # user2, user1
      # user2, user3
      # user3, user2
      # user3, user4
      # user4, user1
      # user4, user3
      # each must be accounted for below:

      user_1_2 = false
      user_1_4 = false
      user_2_1 = false
      user_2_3 = false
      user_3_2 = false
      user_3_4 = false
      user_4_1 = false
      user_4_3 = false

      for i in 0..7
        if result[i]['a_userid'] == user1.id
          if result[i]['b_userid'] == user2.id
            compare_current_score(result[i], user1, user2, 22)
            user_1_2 = true
          else
            # b_userid must be user4
            compare_current_score(result[i], user1, user4, 22)
            user_1_4 = true
          end
        elsif result[i]['a_userid'] == user2.id
          if result[i]['b_userid'] == user1.id
            compare_current_score(result[i], user2, user1, 22)
            user_2_1 = true
          else
            # b_userid must be user3
            compare_current_score(result[i], user2, user3, 22)
            user_2_3 = true
          end
        elsif result[i]['a_userid'] == user3.id
          if result[i]['b_userid'] == user2.id
            compare_current_score(result[i], user3, user2, 22)
            user_3_2 = true
          else
            # b_userid must be user4
            compare_current_score(result[i], user3, user4, 22)
            user_3_4 = true
          end
        else # a_userid must be user4
          if result[i]['b_userid'] == user1.id
            compare_current_score(result[i], user4, user1, 22)
            user_4_1 = true
          else
            # b_userid must be user3
            compare_current_score(result[i], user4, user3, 22)
            user_4_3 = true
          end
        end
      end

      user_1_2.should be_true
      user_1_4.should be_true
      user_2_1.should be_true
      user_2_3.should be_true
      user_3_2.should be_true
      user_3_4.should be_true
      user_4_1.should be_true
      user_4_3.should be_true
    end
  end

  def compare_current_score(r, u1, u2, sc)
    r['alocidispid'].to_i.should == u1.last_jam_locidispid
    r['a_userid'].should == u1.id
    r['a_audio_latency'].to_i.should == u1.last_jam_audio_latency
    r['blocidispid'].to_i.should == u2.last_jam_locidispid
    r['b_userid'].should == u2.id
    r['b_audio_latency'].to_i.should == u2.last_jam_audio_latency
    r['score'].to_i.should == sc
    r['full_score'].to_i.should == (u1.last_jam_audio_latency + u2.last_jam_audio_latency + sc)
  end

  describe "discard_scores" do

    it "works" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
      Score.count.should == 2
      Score.connection.execute("SELECT discard_scores(5)").check
      Score.count.should == 2
    end

    it "discards over 5 items" do
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 6.days.ago)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 5.days.ago)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 4.days.ago)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 3.days.ago)
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 2.days.ago)

      Score.count.should == 10

      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 1.days.ago)

      Score.count.should == 10

      # make a score older than all the rest; it should get whacked
      Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 26, 7.days.ago)

      Score.count.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 5
      Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 5


      Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
      Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
      Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
      Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
      Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
      Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)

      Score.count.should == 20

      Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 10

      Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 36, 7.days.ago)
      Score.count.should == 20
      Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 10

      # let's create scores between a new location, and make sure they don't distrurb the data we have now
      Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)

      Score.count.should == 22

      Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
      Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
      Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
      Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)

      Score.count.should == 30

      Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
      Score.connection.execute("SELECT * FROM scores WHERE score = 10").ntuples.should == 10
    end
  end
end
