def test_match_str(self):
    self.assertFalse(match_str('xy', {'x': 1200}))
    self.assertTrue(match_str('!xy', {'x': 1200}))
    self.assertTrue(match_str('x', {'x': 1200}))
    self.assertFalse(match_str('!x', {'x': 1200}))
    self.assertTrue(match_str('x', {'x': 0}))
    self.assertTrue(match_str('is_live', {'is_live': True}))
    self.assertFalse(match_str('is_live', {'is_live': False}))
    self.assertFalse(match_str('is_live', {'is_live': None}))
    self.assertFalse(match_str('is_live', {}))
    self.assertFalse(match_str('!is_live', {'is_live': True}))
    self.assertTrue(match_str('!is_live', {'is_live': False}))
    self.assertTrue(match_str('!is_live', {'is_live': None}))
    self.assertTrue(match_str('!is_live', {}))
    self.assertTrue(match_str('title', {'title': 'abc'}))
    self.assertTrue(match_str('title', {'title': ''}))
    self.assertFalse(match_str('!title', {'title': 'abc'}))
    self.assertFalse(match_str('!title', {'title': ''}))
    self.assertFalse(match_str('x>0', {'x': 0}))
    self.assertFalse(match_str('x>0', {}))
    self.assertTrue(match_str('x>?0', {}))
    self.assertTrue(match_str('x>1K', {'x': 1200}))
    self.assertFalse(match_str('x>2K', {'x': 1200}))
    self.assertTrue(match_str('x>=1200 & x < 1300', {'x': 1200}))
    self.assertFalse(match_str('x>=1100 & x < 1200', {'x': 1200}))
    self.assertTrue(match_str('x > 1:0:0', {'x': 3700}))
    self.assertFalse(match_str('y=a212', {'y': 'foobar42'}))
    self.assertTrue(match_str('y=foobar42', {'y': 'foobar42'}))
    self.assertFalse(match_str('y!=foobar42', {'y': 'foobar42'}))
    self.assertTrue(match_str('y!=foobar2', {'y': 'foobar42'}))
    self.assertTrue(match_str('y^=foo', {'y': 'foobar42'}))
    self.assertFalse(match_str('y!^=foo', {'y': 'foobar42'}))
    self.assertFalse(match_str('y^=bar', {'y': 'foobar42'}))
    self.assertTrue(match_str('y!^=bar', {'y': 'foobar42'}))
    self.assertRaises(ValueError, match_str, 'x^=42', {'x': 42})
    self.assertTrue(match_str('y*=bar', {'y': 'foobar42'}))
    self.assertFalse(match_str('y!*=bar', {'y': 'foobar42'}))
    self.assertFalse(match_str('y*=baz', {'y': 'foobar42'}))
    self.assertTrue(match_str('y!*=baz', {'y': 'foobar42'}))
    self.assertTrue(match_str('y$=42', {'y': 'foobar42'}))
    self.assertFalse(match_str('y$=43', {'y': 'foobar42'}))
    self.assertFalse(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 90, 'description': 'foo'}))
    self.assertTrue(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 190, 'description': 'foo'}))
    self.assertFalse(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 190, 'dislike_count': 60, 'description': 'foo'}))
    self.assertFalse(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 190, 'dislike_count': 10}))
    self.assertTrue(match_str('x~=\\bbar', {'x': 'foo bar'}))
    self.assertFalse(match_str('x~=\\bbar.+', {'x': 'foo bar'}))
    self.assertFalse(match_str('x~=^FOO', {'x': 'foo bar'}))
    self.assertTrue(match_str('x~=(?i)^FOO', {'x': 'foo bar'}))
    self.assertTrue(match_str('x^="foo"', {'x': 'foo "bar"'}))
    self.assertFalse(match_str('x^="foo  "', {'x': 'foo "bar"'}))
    self.assertFalse(match_str('x$="bar"', {'x': 'foo "bar"'}))
    self.assertTrue(match_str('x$=" \\"bar\\""', {'x': 'foo "bar"'}))
    self.assertFalse(match_str('x=foo & bar', {'x': 'foo & bar'}))
    self.assertTrue(match_str('x=foo \\& bar', {'x': 'foo & bar'}))
    self.assertTrue(match_str('x=foo \\& bar & x^=foo', {'x': 'foo & bar'}))
    self.assertTrue(match_str('x="foo \\& bar" & x^=foo', {'x': 'foo & bar'}))
    self.assertTrue(match_str("!is_live & like_count>?100 & description~='(?i)\\bcats \\& dogs\\b'", {'description': 'Raining Cats & Dogs'}))
    self.assertFalse(match_str('id!=foo', {'id': 'foo'}, True))
    self.assertTrue(match_str('x', {'id': 'foo'}, True))
    self.assertTrue(match_str('!x', {'id': 'foo'}, True))
    self.assertFalse(match_str('x', {'id': 'foo'}, False))
def test_match_str(self):
    self.assertFalse(match_str('xy', {'x': 1200}))
    self.assertTrue(match_str('!xy', {'x': 1200}))
    self.assertTrue(match_str('x', {'x': 1200}))
    self.assertFalse(match_str('!x', {'x': 1200}))
    self.assertTrue(match_str('x', {'x': 0}))
    self.assertTrue(match_str('is_live', {'is_live': True}))
    self.assertFalse(match_str('is_live', {'is_live': False}))
    self.assertFalse(match_str('is_live', {'is_live': None}))
    self.assertFalse(match_str('is_live', {}))
    self.assertFalse(match_str('!is_live', {'is_live': True}))
    self.assertTrue(match_str('!is_live', {'is_live': False}))
    self.assertTrue(match_str('!is_live', {'is_live': None}))
    self.assertTrue(match_str('!is_live', {}))
    self.assertTrue(match_str('title', {'title': 'abc'}))
    self.assertTrue(match_str('title', {'title': }))
    self.assertFalse(match_str('!title', {'title': 'abc'}))
    self.assertFalse(match_str('!title', {'title': }))
    self.assertFalse(match_str('x>0', {'x': 0}))
    self.assertFalse(match_str('x>0', {}))
    self.assertTrue(match_str('x>?0', {}))
    self.assertTrue(match_str('x>1K', {'x': 1200}))
    self.assertFalse(match_str('x>2K', {'x': 1200}))
    self.assertTrue(match_str('x>=1200 & x < 1300', {'x': 1200}))
    self.assertFalse(match_str('x>=1100 & x < 1200', {'x': 1200}))
    self.assertTrue(match_str('x > 1:0:0', {'x': 3700}))
    self.assertFalse(match_str('y=a212', {'y': 'foobar42'}))
    self.assertTrue(match_str('y=foobar42', {'y': 'foobar42'}))
    self.assertFalse(match_str('y!=foobar42', {'y': 'foobar42'}))
    self.assertTrue(match_str('y!=foobar2', {'y': 'foobar42'}))
    self.assertTrue(match_str('y^=foo', {'y': 'foobar42'}))
    self.assertFalse(match_str('y!^=foo', {'y': 'foobar42'}))
    self.assertFalse(match_str('y^=bar', {'y': 'foobar42'}))
    self.assertTrue(match_str('y!^=bar', {'y': 'foobar42'}))
    self.assertRaises(ValueError, match_str, 'x^=42', {'x': 42})
    self.assertTrue(match_str('y*=bar', {'y': 'foobar42'}))
    self.assertFalse(match_str('y!*=bar', {'y': 'foobar42'}))
    self.assertFalse(match_str('y*=baz', {'y': 'foobar42'}))
    self.assertTrue(match_str('y!*=baz', {'y': 'foobar42'}))
    self.assertTrue(match_str('y$=42', {'y': 'foobar42'}))
    self.assertFalse(match_str('y$=43', {'y': 'foobar42'}))
    self.assertFalse(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 90, 'description': 'foo'}))
    self.assertTrue(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 190, 'description': 'foo'}))
    self.assertFalse(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 190, 'dislike_count': 60, 'description': 'foo'}))
    self.assertFalse(match_str('like_count > 100 & dislike_count <? 50 & description', {'like_count': 190, 'dislike_count': 10}))
    self.assertTrue(match_str('x~=\\bbar', {'x': 'foo bar'}))
    self.assertFalse(match_str('x~=\\bbar.+', {'x': 'foo bar'}))
    self.assertFalse(match_str('x~=^FOO', {'x': 'foo bar'}))
    self.assertTrue(match_str('x~=(?i)^FOO', {'x': 'foo bar'}))
    self.assertTrue(match_str('x^="foo"', {'x': 'foo "bar"'}))
    self.assertFalse(match_str('x^="foo  "', {'x': 'foo "bar"'}))
    self.assertFalse(match_str('x$="bar"', {'x': 'foo "bar"'}))
    self.assertTrue(match_str('x$=" \\"bar\\', {'x': 'foo "bar"'}))
    self.assertFalse(match_str('x=foo & bar', {'x': 'foo & bar'}))
    self.assertTrue(match_str('x=foo \\& bar', {'x': 'foo & bar'}))
    self.assertTrue(match_str('x=foo \\& bar & x^=foo', {'x': 'foo & bar'}))
    self.assertTrue(match_str('x="foo \\& bar" & x^=foo', {'x': 'foo & bar'}))
    self.assertTrue(match_str("!is_live & like_count>?100 & description~='(?i)\\bcats \\& dogs\\b'", {'description': 'Raining Cats & Dogs'}))
    self.assertFalse(match_str('id!=foo', {'id': 'foo'}, True))
    self.assertTrue(match_str('x', {'id': 'foo'}, True))
    self.assertTrue(match_str('!x', {'id': 'foo'}, True))
    self.assertFalse(match_str('x', {'id': 'foo'}, False))