<commit_before>Screw.Matchers = {
  expect: function(actual) {
    return {
      to: function(matcher, expected, not) {
        var matched = matcher.match(expected, actual);
        if (not ? matched : !matched) {
          throw(matcher.failure_message(expected, actual, not));
        }
      },
      to_not: function(matcher, expected) {
        this.to(matcher, expected, true);
      }
    }
  },
  equal: {
    match: function(expected, actual) {
      if (Screw.Matchers.equal.by_type[expected.constructor.name])
        return Screw.Matchers.equal.by_type[expected.constructor.name](expected, actual);
      else
        return expected == actual;
    },
    failure_message: function(expected, actual, not) {
      return 'expected ' + $([actual]).print() + (not ? ' to not equal ' : ' to equal ') + $([expected]).print();
    },
    by_type: {
      Array: function(expected, actual) {
        for (var i = 0; i < actual.length; i++)
          if (!Screw.Matchers.equal.match(expected[i], actual[i])) return false;
        return actual.length == expected.length;
      },
      Object: function(expected, actual) {
        for (var key in expected)
          if (!Screw.Matchers.equal.match(expected[key], actual[key])) return false;
        for (var key in actual)
          if (!Screw.Matchers.equal.match(actual[key], expected[key])) return false;
        return true;
      }
    }
  },
  match: {
    match: function(expected, actual) {
      if (expected.constructor == String) {
        return actual.indexOf(expected) > -1;
      } else {
        return expected.exec(actual);
      }
    },
    failure_message: function(expected, actual, not) {
      return 'expected ' + $([actual]).print() + (not ? ' to not match ' : ' to match ') + $([expected]).print();
    }
  },
  be_empty: {
    match: function(expected, actual) {
      if (actual.length == undefined) {
        throw(actual.toString() + " does not respond to length");
      }
      return actual.length == 0;
    },
    failure_message: function(expected, actual, not) {
      return 'expected ' + $([actual]).print() + (not ? ' to not be empty' : ' to be empty');
    }
  }
}<commit_msg>should be compatible w/ Safari now<commit_after>Screw.Matchers = {
  expect: function(actual) {
    return {
      to: function(matcher, expected, not) {
        var matched = matcher.match(expected, actual);
        if (not ? matched : !matched) {
          throw(matcher.failure_message(expected, actual, not));
        }
      },
      to_not: function(matcher, expected) {
        this.to(matcher, expected, true);
      }
    }
  },
  equal: {
    match: function(expected, actual) {
      if (Screw.Matchers.equal.by_type[expected.constructor])
        return Screw.Matchers.equal.by_type[expected.constructor](expected, actual);
      else
        return expected == actual;
    },
    failure_message: function(expected, actual, not) {
      return 'expected ' + $([actual]).print() + (not ? ' to not equal ' : ' to equal ') + $([expected]).print();
    }
  },
  match: {
    match: function(expected, actual) {
      if (expected.constructor == String) {
        return actual.indexOf(expected) > -1;
      } else {
        return expected.exec(actual);
      }
    },
    failure_message: function(expected, actual, not) {
      return 'expected ' + $([actual]).print() + (not ? ' to not match ' : ' to match ') + $([expected]).print();
    }
  },
  be_empty: {
    match: function(expected, actual) {
      if (actual.length == undefined) {
        throw(actual.toString() + " does not respond to length");
      }
      return actual.length == 0;
    },
    failure_message: function(expected, actual, not) {
      return 'expected ' + $([actual]).print() + (not ? ' to not be empty' : ' to be empty');
    }
  }
};

Screw.Matchers.equal.by_type = {};
Screw.Matchers.equal.by_type[Array] = function(expected, actual) {
  for (var i = 0; i < actual.length; i++)
    if (!Screw.Matchers.equal.match(expected[i], actual[i])) return false;
  return actual.length == expected.length;
};

Screw.Matchers.equal.by_type[Object] = function(expected, actual) {
  for (var key in expected)
    if (!Screw.Matchers.equal.match(expected[key], actual[key])) return false;
  for (var key in actual)
    if (!Screw.Matchers.equal.match(actual[key], expected[key])) return false;
  return true;
};
{'fraction_non_alphanumeric': 0.1543747136967476, 'fraction_numerical': 0.001374255611543747, 'mean_word_length': 2.7071307300509337, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '620642', 'n_tokens_mistral': 1347, 'n_tokens_neox': 1327, 'n_words': 313}