Tinytest.add('minimongo - wrapTransform', test => {
  const wrap = LocalCollection.wrapTransform;

  // Transforming no function gives falsey.
  test.isFalse(wrap(undefined));
  test.isFalse(wrap(null));

  // It's OK if you don't change the ID.
  const validTransform = doc => {
    delete doc.x;
    doc.y = 42;
    doc.z = () => 43;
    return doc;
  };
  const transformed = wrap(validTransform)({_id: 'asdf', x: 54});
  test.equal(Object.keys(transformed), ['_id', 'y', 'z']);
  test.equal(transformed.y, 42);
  test.equal(transformed.z(), 43);

  // Ensure that ObjectIDs work (even if the _ids in question are not ===-equal)
  const oid1 = new MongoID.ObjectID();
  const oid2 = new MongoID.ObjectID(oid1.toHexString());
  test.equal(wrap(() => ({
    _id: oid2,
  }))({_id: oid1}),
  {_id: oid2});

  // transform functions must return objects
  const invalidObjects = [
    'asdf', new MongoID.ObjectID(), false, null, true,
    27, [123], /adsf/, new Date, () => {}, undefined,
  ];
  invalidObjects.forEach(invalidObject => {
    const wrapped = wrap(() => invalidObject);
    test.throws(() => {
      wrapped({_id: 'asdf'});
    });
  }, /transform must return object/);

  // transform functions may not change _ids
  const wrapped = wrap(doc => { doc._id = 'x'; return doc; });
  test.throws(() => {
    wrapped({_id: 'y'});
  }, /can't have different _id/);

  // transform functions may remove _ids
  test.equal({_id: 'a', x: 2},
    wrap(d => {delete d._id; return d;})({_id: 'a', x: 2}));

  // test that wrapped transform functions are nonreactive
  const unwrapped = doc => {
    test.isFalse(Tracker.active);
    return doc;
  };
  const handle = Tracker.autorun(() => {
    test.isTrue(Tracker.active);
    wrap(unwrapped)({_id: 'xxx'});
  });
  handle.stop();
});

Tinytest.add('minimongo - bulk remove with $in operator removes all matching documents', function(test) {
  const coll = new LocalCollection();
  
  // Insert multiple documents
  const ids = ['id1', 'id2', 'id3', 'id4'];
  ids.forEach(id => {
    coll.insert({ _id: id, value: `item-${id}` });
  });
  
  // Verify we have 4 documents
  test.equal(coll.find().count(), 4);
  
  // Remove 2 documents using $in operator
  const removedCount = coll.remove({ _id: { $in: ['id1', 'id2'] } });
  
  // This should remove 2 documents, not just 1
  test.equal(removedCount, 2);
  
  // Verify only 2 documents remain
  test.equal(coll.find().count(), 2);
  
  // Verify the correct documents were removed
  test.isUndefined(coll.findOne('id1'));
  test.isUndefined(coll.findOne('id2'));
  
  // Verify the other documents still exist
  test.isNotUndefined(coll.findOne('id3'));
  test.isNotUndefined(coll.findOne('id4'));
});

if (Meteor.isClient) {
  Tinytest.add('minimongo - $geoIntersects should throw error', function(test) {
    const collection = new LocalCollection();
    collection.insert({ _id: 'a', loc: { type: 'Point', coordinates: [0, 0] } });

    const query = {
      loc: {
        $geoIntersects: {
          $geometry: {
            type: 'Polygon',
            coordinates: [
              [
                [0, 0], [0, 1], [1, 1], [1, 0], [0, 0]
              ]
            ]
          }
        }
      }
    };

    test.throws(
      () => collection.findOne(query),
      /Unrecognized operator: \$geoIntersects/,
      'Should throw error for $geoIntersects in Minimongo'
    );
  });
}