desc: Tests replacement of selections
tests:

    # Set up some data
    - cd: r.db('test').table_create('test1')
      ot: ({'created':1})

    - def: tbl = r.db('test').table('test1')

    - cd: r.db('test').table_create('test2')
      ot: ({'created':1})

    - def: tbl2 = r.db('test').table('test2')
      cd: []

    - py: tbl.insert([{'id':i} for i in xrange(100)])
      js: |
        tbl.insert(function(){
            var res = []
            for (var i = 0; i < 100; i++) {
                res.push({id:i});
            }
            return res;
        }())
      rb: tbl.insert((1..100).map{ |i| {:id => i } })
      ot: ({'deleted':0.0,'replaced':0.0,'unchanged':0.0,'errors':0.0,'skipped':0.0,'inserted':100})

    - cd: tbl.count()
      ot: 100

    # Identity

    - py: tbl.get(12).replace(lambda row:{'id':row['id']})
      js: tbl.get(12).replace(function(row) { return {'id':row('id')}; })
      rb: tbl.get(12).replace{ |row| { :id => row[:id] } }
      ot: ({'deleted':0.0,'replaced':0.0,'unchanged':1,'errors':0.0,'skipped':0.0,'inserted':0.0})

    # Replace single row

    - py: tbl.get(12).replace(lambda row:{'id':row['id'], 'a':row['id']})
      js: tbl.get(12).replace(function(row) { return {'id':row('id'), 'a':row('id')}; })
      rb: tbl.get(12).replace{ |row| { :id => row[:id], :a => row[:id] } }
      ot: ({'deleted':0.0,'replaced':1,'unchanged':0.0,'errors':0.0,'skipped':0.0,'inserted':0.0})

    - py: tbl.get(13).replace(lambda row:None)
      js: tbl.get(13).replace(function(row) { return null; })
      rb: tbl.get(13).replace{ |row| nil }
      ot: ({'deleted':1,'replaced':0.0,'unchanged':0.0,'errors':0.0,'skipped':0.0,'inserted':0.0})

    # Replace selection of table

    - py: tbl.between(10, 20, right_bound='closed').replace(lambda row:{'a':1})
      js: tbl.between(10, 20, {'right_bound':'closed'}).replace(function(row) { return {'a':1}; })
      ot: ({'first_error':'Inserted object must have primary key `id`:\n{\n\t\"a\":\t1\n}','deleted':0.0,'replaced':0.0,'unchanged':0.0,'errors':10,'skipped':0.0,'inserted':0.0})


    - py: tbl.filter(lambda row:(row['id'] >= 10) & (row['id'] < 20)).replace(lambda row:{'id':row['id'], 'a':row['id']})
      js: tbl.filter(function(row) { return row('id').ge(10).and(row('id').lt(20))}).replace(function(row) { return {'id':row('id'), 'a':row('id')}; })
      rb: tbl.filter{ |row|
            (row[:id] >= 10).and(row[:id] < 20)
          }.replace{ |row|
            { :id => row[:id], :a => row[:id] } }
      ot: ({'deleted':0.0,'replaced':8,'unchanged':1,'errors':0.0,'skipped':0.0,'inserted':0.0})

    # trying to change pkey of a document
    - py: tbl.get(1).replace({'id':2,'a':1})
      ot:
        cd: ({'first_error':'Primary key `id` cannot be changed (`{\n\t"id":\t1\n}` -> `{\n\t"a":\t1,\n\t"id":\t2\n}`).','deleted':0.0,'replaced':0.0,'unchanged':0.0,'errors':1,'skipped':0.0,'inserted':0.0})


    # not passing a pkey in the first place
    - cd: tbl.get(1).replace({'a':1})
      rb: [] # the ruby test driver cannot parse the expected error message
      ot: ({'first_error':'Inserted object must have primary key `id`:\n{\n\t"a":\t1\n}','deleted':0.0,'replaced':0.0,'unchanged':0.0,'errors':1,'skipped':0.0,'inserted':0.0})

    # check r.row, static value and otherwise
    - py: tbl.get(1).replace({'id':r.row['id'],'a':'b'})
      js: tbl.get(1).replace({'id':r.row('id'),'a':'b'})
      rb: tbl.get(1).replace{ |row| { :id => row[:id], :a => 'b' } }
      ot: ({'deleted':0.0,'replaced':1,'unchanged':0.0,'errors':0.0,'skipped':0.0,'inserted':0.0})

    - cd: tbl.get(1).replace(r.row.merge({'a':'b'}))
      rb: tbl.get(1).replace{ |row| row.merge({'a':'b'}) }
      ot: ({'deleted':0.0,'replaced':0.0,'unchanged':1,'errors':0.0,'skipped':0.0,'inserted':0.0})

    # test atomicity constraints
    - cd: tbl.get(1).replace(r.row.merge({'c':r.js('5')}))
      rb: tbl.get(1).replace{ |row| row.merge({'c':r.js('5')}) }
      ot: err('RqlRuntimeError', 'Could not prove function deterministic.  Maybe you want to use the non_atomic flag?', [0])

    - cd: tbl.get(1).replace(r.row.merge({'c':tbl.nth(0)}))
      rb: tbl.get(1).replace{ |row| row.merge({'c':tbl.nth(0)}) }
      ot: err('RqlRuntimeError', 'Could not prove function deterministic.  Maybe you want to use the non_atomic flag?', [0])

    - py: tbl.get(1).replace(r.row.merge({'c':r.js('5')}), non_atomic=True)
      js: tbl.get(1).replace(r.row.merge({'c':r.js('5')}), {'nonAtomic':true})
      rb: tbl.get(1).replace({ :non_atomic => true }){ |row| row.merge({ :c => r.js('5') })}
      ot: ({'deleted':0.0,'replaced':1,'unchanged':0.0,'errors':0.0,'skipped':0.0,'inserted':0.0})

    - js: tbl.get(1).replace({}, 'foo')
      cd: []
      ot: err('RqlDriverError', 'Expected 1 argument(s) but found 2.')

    - js: tbl.get(1).replace({}, {'foo':'bar'})
      cd: []
      ot: err('RqlCompileError', 'Unrecognized optional argument `foo`.')

    # Replace whole table

    - py: tbl.replace(lambda row:None)
      js: tbl.replace(function(row) { return null; })
      rb: tbl.replace{ |row| nil }
      ot: ({'deleted':99,'replaced':0.0,'unchanged':0.0,'errors':0.0,'skipped':0.0,'inserted':0.0})

    # clean up
    - cd: r.db('test').table_drop('test1')
      ot: "({'dropped':1})"
    - cd: r.db('test').table_drop('test2')
      ot: "({'dropped':1})"
