'use strict';

var Immutable = require('immutable');

var slice = Array.prototype.slice;

var partial = function (func) {
  var boundArgs = slice.call(arguments, 1);

  return function () {
    var args = boundArgs.concat(slice.call(arguments));
    return func.apply(this, args);
  };
};

var passes = function (a, b) {
  return (!a ^ !b);
};

var compares = function (func) {
  return {
    compare: partial(func, false),
    negativeCompare: partial(func, true)
  };
};

module.exports = {
  toBeImmutable: function () {
    return compares(function (not, actual) {
      return {
        pass: passes(Immutable.Iterable.isIterable(actual), not),
        message: `Expected ${actual.toString()}${not ? ' not' : ''} to be immutable`
      };
    });
  },

  toEqualImmutable: function () {
    return compares(function (not, actual, expected) {
      return {
        pass: passes(Immutable.is(actual, expected), not),
        message: `Expected ${actual.toString()}${not ? ' not' : ''} to equal ${expected.toString()}`
      };
    });
  }
};

@@ -467,16 +467,127 @@
  %7D;%0A%7D;%0A%0A
+var toString = function (obj) %7B%0A  return obj && typeof obj.toString === 'function' ? obj.toString() : obj;%0A%7D;%0A%0A
 module.e
@@ -775,39 +775,32 @@
 ge: %60Expected $%7B
-actual.
 toString()%7D$%7Bnot
@@ -784,32 +784,38 @@
 cted $%7BtoString(
+actual
 )%7D$%7Bnot ? ' not'
@@ -1057,15 +1057,8 @@
 d $%7B
-actual.
 toSt
@@ -1062,16 +1062,22 @@
 oString(
+actual
 )%7D$%7Bnot 
@@ -1106,17 +1106,8 @@
 l $%7B
-expected.
 toSt
@@ -1111,16 +1111,24 @@
 oString(
+expected
 )%7D%60%0A    

Deal with undefined and null values