def setUp(self):
     self._split_parser = SplitParser(object())
     matcher = {
         'matcherType': 'PART_OF_SET',
         'whitelistMatcherData': {'whitelist': ['ABC', 'DEF', 'GHI']}
     }
     split = {'conditions': [{'matcher': matcher}]}
     self._matcher = (self._split_parser._parse_matcher(split, matcher)
                      ._matcher.delegate)
 def setUp(self):
     self._split_parser = SplitParser(object())
     matcher = {
         'matcherType': 'EQUAL_TO_BOOLEAN',
         'booleanMatcherData': True
     }
     split = {'conditions': [{'matcher': matcher}]}
     self._matcher = (self._split_parser._parse_matcher(split, matcher)
                      ._matcher.delegate)
 def setUp(self):
     self._split_parser = SplitParser(object())
     matcher = {
         'matcherType': 'MATCHES_STRING',
         'stringMatcherData': '[a-z]'
     }
     split = {'conditions': [{'matcher': matcher}]}
     self._matcher = (self._split_parser._parse_matcher(split, matcher)
                      ._matcher.delegate)
 def setUp(self):
     self._split_parser = SplitParser(object())
     matcher = {
         'matcherType': 'IN_SPLIT_TREATMENT',
         'dependencyMatcherData': {
             'split': 'someSplit',
             'treatments': ['on']
         }
     }
     split = {'conditions': [{'matcher': matcher}]}
     self._matcher = (self._split_parser._parse_matcher(split, matcher)
                      ._matcher.delegate)
     self._mock = self.patch('splitio.clients.MatcherClient')
class SplitParserParseCombinerTests(TestCase):
    def setUp(self):
        self.some_segment_fetcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)

    def test_returns_and_combiner(self):
        """Tests that _parse_combiner returns an AndCombiner"""
        self.assertIsInstance(self.parser._parse_combiner('AND'), AndCombiner)

    def test_raises_exception_on_invalid_combiner(self):
        """Tests that _parse_combiner raises an exception on an invalid combiner"""
        with self.assertRaises(ValueError):
            self.parser._parse_combiner('foobar')
class BooleanMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'EQUAL_TO_BOOLEAN',
            'booleanMatcherData': True
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, BooleanMatcher)

    def test_different_keys(self):
        '''
        Test how different types get parsed
        '''
        self.assertTrue(self._matcher.match(True))
        self.assertTrue(self._matcher.match('tRue'))
        self.assertFalse(self._matcher.match(False))
        self.assertFalse(self._matcher.match('False'))
        self.assertFalse(self._matcher.match(''))
        self.assertFalse(self._matcher.match({}))
class RegexMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'MATCHES_STRING',
            'stringMatcherData': '[a-z]'
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, RegexMatcher)

    def test_regexes(self):
        '''
        Test different regexes lodeded from regex.txt
        '''
        current_path = os.path.dirname(__file__)
        with open(os.path.join(current_path, 'regex.txt')) as flo:
            lines = [line for line in flo]
        lines.pop()  # Remove empy last line
        for line in lines:
            regex, text, res = line.split('#')
            matcher = RegexMatcher(regex)
            print(regex, text, res)
            self.assertEquals(matcher.match(text), json.loads(res))
class DependencyMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'IN_SPLIT_TREATMENT',
            'dependencyMatcherData': {
                'split': 'someSplit',
                'treatments': ['on']
            }
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)
        self._mock = self.patch('splitio.clients.MatcherClient')

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, DependencyMatcher)

    def test_matcher_client_is_created_and_get_treatment_called(self):
        self._matcher.match('abc', None, self._mock)
        self._mock.get_treatment.assert_called_once_with('abc', 'someSplit', None)
        self.assertTrue(True)
    def setUp(self):
        self.some_partial_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()

        self.combining_matcher_mock = self.patch(
            'splitio.splits.CombiningMatcher')
        self.parser = SplitParser(self.some_segment_fetcher)
        self.parse_matcher_mock = self.patch_object(self.parser,
                                                    '_parse_matcher')
        self.parse_matcher_side_effect = [mock.MagicMock() for _ in range(2)]
        self.parse_matcher_mock.side_effect = self.parse_matcher_side_effect
        self.parse_combiner_mock = self.patch_object(self.parser,
                                                     '_parse_combiner')

        self.some_matchers = [mock.MagicMock(), mock.MagicMock()]
        self.some_matcher_group = {
            'matchers': self.some_matchers,
            'combiner': mock.MagicMock()
        }
    def setUp(self):
        self.some_partial_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()
        self.some_matcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)

        self.get_matcher_data_data_type_mock = self.patch_object(
            self.parser, '_get_matcher_data_data_type')
        self.equal_to_matcher_mock = self.patch(
            'splitio.splits.EqualToMatcher')
        self.greater_than_or_equal_to_matcher_mock = self.patch(
            'splitio.splits.GreaterThanOrEqualToMatcher')
        self.less_than_or_equal_to_matcher_mock = self.patch(
            'splitio.splits.LessThanOrEqualToMatcher')
        self.between_matcher_mock = self.patch('splitio.splits.BetweenMatcher')

        self.some_in_segment_matcher = {
            'matcherType': 'IN_SEGMENT',
            'userDefinedSegmentMatcherData': {
                'segmentName': mock.MagicMock()
            }
        }
        self.some_whitelist_matcher = {
            'matcherType': 'WHITELIST',
            'whitelistMatcherData': {
                'whitelist': mock.MagicMock()
            }
        }
        self.some_equal_to_matcher = self._get_unary_number_matcher('EQUAL_TO')
        self.some_greater_than_or_equal_to_matcher = self._get_unary_number_matcher(
            'GREATER_THAN_OR_EQUAL_TO')
        self.some_less_than_or_equal_to_matcher = self._get_unary_number_matcher(
            'LESS_THAN_OR_EQUAL_TO')
        self.some_between_matcher = {
            'matcherType': 'BETWEEN',
            'betweenMatcherData': {
                'start': mock.MagicMock(),
                'end': mock.MagicMock(),
            }
        }
    def setUp(self):
        self.some_partial_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()
        self.some_matcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)

        self.parse_matcher_all_keys_mock = self.patch_object(
            self.parser, '_parse_matcher_all_keys')
        self.parse_matcher_in_segment_mock = self.patch_object(
            self.parser, '_parse_matcher_in_segment')
        self.parse_matcher_whitelist_mock = self.patch_object(
            self.parser, '_parse_matcher_whitelist')
        self.parse_matcher_equal_to_mock = self.patch_object(
            self.parser, '_parse_matcher_equal_to')
        self.parse_matcher_greater_than_or_equal_to_mock = self.patch_object(
            self.parser, '_parse_matcher_greater_than_or_equal_to')
        self.parse_matcher_less_than_or_equal_to_mock = self.patch_object(
            self.parser, '_parse_matcher_less_than_or_equal_to')
        self.parse_matcher_between_mock = self.patch_object(
            self.parser, '_parse_matcher_between')

        self.parser._parse_matcher_fake = mock.MagicMock()
Beispiel #12
0
    def _build_split_fetcher(self):
        """
        Build the json backed split fetcher
        :return: The json backed split fetcher
        :rtype: JSONFileSplitFetcher
        """
        segment_fetcher = JSONFileSegmentFetcher(self._segment_changes_file_name)
        split_parser = SplitParser(segment_fetcher)
        split_fetcher = JSONFileSplitFetcher(
            self._split_changes_file_name,
            split_parser
        )

        return split_fetcher
class SplitParserParseTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self.some_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)
        self.internal_parse_mock = self.patch_object(self.parser, '_parse')

    def test_parse_calls_internal_parse(self):
        """Tests that parse calls _parse with block_until_ready as False"""
        self.parser.parse(self.some_split)
        self.internal_parse_mock.assert_called_once_with(
            self.some_split, block_until_ready=False)

    def test_parse_calls_internal_parse_with_block_until_ready(self):
        """Tests that parse calls _parse passing the value of block_until_ready"""
        self.parser.parse(self.some_split, block_until_ready=True)
        self.internal_parse_mock.assert_called_once_with(
            self.some_split, block_until_ready=True)

    def test_parse_returns_none_if_internal_parse_raises_an_exception(self):
        """Tests that parse returns None if _parse raises an exception"""
        self.internal_parse_mock.side_effect = Exception()
        self.assertIsNone(self.parser.parse(self.some_split))
class ContainsStringMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'CONTAINS_STRING',
            'whitelistMatcherData': {'whitelist': ['ABC', 'DEF', 'GHI']}
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, ContainsStringMatcher)

    def test_keys_with_string(self):
        '''
        Test that keys starting with one of the prefixes in the condition match
        '''
        self.assertTrue(self._matcher.match('testABC'))
        self.assertTrue(self._matcher.match('testDEFabc'))
        self.assertTrue(self._matcher.match('GHI3214'))

    def test_keys_without_string_dont_match(self):
        '''
        Test that keys that dont start with one of the prefixes don't match.
        '''
        self.assertFalse(self._matcher.match('testJKL'))
        self.assertFalse(self._matcher.match('test123'))
        self.assertFalse(self._matcher.match('testdl_'))

    def test_empty_string_doesnt_match(self):
        '''
        Tests that the empty string doesn't match.
        '''
        self.assertFalse(self._matcher.match(''))

    def test_none_doesnt_match(self):
        '''
        Tests that None doesn't match.
        '''
        self.assertFalse(self._matcher.match(None))
class StartsWithMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'STARTS_WITH',
            'whitelistMatcherData': {'whitelist': ['ABC', 'DEF', 'GHI']}
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, StartsWithMatcher)

    def test_keys_with_prefix_match(self):
        '''
        Test that keys starting with one of the prefixes in the condition match
        '''
        self.assertTrue(self._matcher.match('ABCtest'))
        self.assertTrue(self._matcher.match('DEFtest'))
        self.assertTrue(self._matcher.match('GHItest'))

    def test_keys_without_prefix_dont_match(self):
        '''
        Test that keys that dont start with one of the prefixes don't match.
        '''
        self.assertFalse(self._matcher.match('JKLtest'))
        self.assertFalse(self._matcher.match('123test'))
        self.assertFalse(self._matcher.match('dl_test'))

    def test_empty_string_doesnt_match(self):
        '''
        Tests that the empty string doesn't match.
        '''
        self.assertFalse(self._matcher.match(''))

    def test_none_doesnt_match(self):
        '''
        Tests that None doesn't match.
        '''
        self.assertFalse(self._matcher.match(None))
class PartOfSetMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'PART_OF_SET',
            'whitelistMatcherData': {'whitelist': ['ABC', 'DEF', 'GHI']}
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, PartOfSetMatcher)

    def test_subset_of_set_matches(self):
        '''
        Test that a subset of the set matches
        '''
        self.assertTrue(self._matcher.match(['ABC', 'DEF', 'GHI']))
        self.assertTrue(self._matcher.match(['ABC']))

    def test_not_subset_of_set_doesnt_match(self):
        '''
        Test that any set with elements that are not in the split's set doesn't
        match
        '''
        self.assertFalse(self._matcher.match(['ABC', 'DEF', 'GHI', 'AWE']))
        self.assertFalse(self._matcher.match(['RFV']))

    def test_empty_set_doesnt_match(self):
        '''
        Tests that an empty set doesn't match
        '''
        self.assertFalse(self._matcher.match([]))

    def test_none_doesnt_match(self):
        '''
        Tests that None doesn't match.
        '''
        self.assertFalse(self._matcher.match(None))
Beispiel #17
0
 def _build_split_fetcher(self):
     """
     Build the self refreshing split fetcher
     :return: The self refreshing split fetcher
     :rtype: SelfRefreshingSplitFetcher
     """
     segment_change_fetcher = ApiSegmentChangeFetcher(self._sdk_api)
     segment_fetcher = SelfRefreshingSegmentFetcher(
         segment_change_fetcher,
         interval=self._segment_fetcher_interval
     )
     split_change_fetcher = ApiSplitChangeFetcher(self._sdk_api)
     split_parser = SplitParser(segment_fetcher)
     split_fetcher = SelfRefreshingSplitFetcher(
         split_change_fetcher,
         split_parser,
         interval=self._split_fetcher_interval
     )
     return split_fetcher
class ContainsAnyOfSetMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'CONTAINS_ANY_OF_SET',
            'whitelistMatcherData': {'whitelist': ['ABC', 'DEF', 'GHI']}
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, ContainsAnyOfSetMatcher)

    def test_set_with_at_least_one_key(self):
        '''
        Test that a set with at least one key matches
        '''
        self.assertTrue(self._matcher.match(['ABC', 'DEF', 'GHI']))
        self.assertTrue(self._matcher.match(['ABC', 'DEF', 'GHI', 'AWE']))
        self.assertTrue(self._matcher.match(['ABC', 'DEF']))

    def test_set_without_any_key_doesnt_match(self):
        '''
        Test that a set without any the keys doesn't match
        '''
        self.assertFalse(self._matcher.match(['AWE']))

    def test_empty_set_doesnt_match(self):
        '''
        Tests that an empty set doesn't match
        '''
        self.assertFalse(self._matcher.match([]))

    def test_none_doesnt_match(self):
        '''
        Tests that None doesn't match.
        '''
        self.assertFalse(self._matcher.match(None))
class EqualToSetMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self._split_parser = SplitParser(object())
        matcher = {
            'matcherType': 'EQUAL_TO_SET',
            'whitelistMatcherData': {'whitelist': ['ABC', 'DEF', 'GHI']}
        }
        split = {'conditions': [{'matcher': matcher}]}
        self._matcher = (self._split_parser._parse_matcher(split, matcher)
                         ._matcher.delegate)

    def test_matcher_construction(self):
        '''
        Tests that the correct matcher matcher is constructed.
        '''
        self.assertIsInstance(self._matcher, EqualToSetMatcher)

    def test_equal_set_matches(self):
        '''
        Test that the exact same set matches
        '''
        self.assertTrue(self._matcher.match(['ABC', 'DEF', 'GHI']))

    def test_different_set_doesnt_match(self):
        '''
        Test that a different set doesn't match
        '''
        self.assertFalse(self._matcher.match(['ABC', 'DEF', 'GHI', 'AWE']))
        self.assertFalse(self._matcher.match(['ABC']))

    def test_empty_set_doesnt_match(self):
        '''
        Tests that an empty set doesn't match
        '''
        self.assertFalse(self._matcher.match([]))

    def test_none_doesnt_match(self):
        '''
        Tests that None doesn't match.
        '''
        self.assertFalse(self._matcher.match(None))
    def setUp(self):
        self.some_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)
        self.internal_parse_mock = self.patch_object(self.parser, '_parse')
class SplitParserParseMatcherTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self.some_partial_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()
        self.some_matcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)

        self.parse_matcher_all_keys_mock = self.patch_object(
            self.parser, '_parse_matcher_all_keys')
        self.parse_matcher_in_segment_mock = self.patch_object(
            self.parser, '_parse_matcher_in_segment')
        self.parse_matcher_whitelist_mock = self.patch_object(
            self.parser, '_parse_matcher_whitelist')
        self.parse_matcher_equal_to_mock = self.patch_object(
            self.parser, '_parse_matcher_equal_to')
        self.parse_matcher_greater_than_or_equal_to_mock = self.patch_object(
            self.parser, '_parse_matcher_greater_than_or_equal_to')
        self.parse_matcher_less_than_or_equal_to_mock = self.patch_object(
            self.parser, '_parse_matcher_less_than_or_equal_to')
        self.parse_matcher_between_mock = self.patch_object(
            self.parser, '_parse_matcher_between')

        self.parser._parse_matcher_fake = mock.MagicMock()

    def _get_matcher(self, matcher_type):
        return {
            'matcherType': matcher_type,
            'negate': mock.MagicMock(),
            'keySelector': {
                'attribute': mock.MagicMock()
            }
        }

    def test_calls_parse_matcher_all_keys(self):
        """Test that _parse_matcher calls _parse_matcher_all_keys on ALL_KEYS matcher"""
        matcher = self._get_matcher('ALL_KEYS')
        self.parser._parse_matcher(self.some_partial_split, matcher)
        self.parse_matcher_all_keys_mock.assert_called_once_with(
            self.some_partial_split, matcher, block_until_ready=False)

    def test_calls_parse_matcher_in_segment(self):
        """Test that _parse_matcher calls _parse_matcher_in_segment on IN_SEGMENT matcher"""
        matcher = self._get_matcher('IN_SEGMENT')
        self.parser._parse_matcher(self.some_partial_split, matcher)
        self.parse_matcher_in_segment_mock.assert_called_once_with(
            self.some_partial_split, matcher, block_until_ready=False)

    def test_calls_parse_matcher_whitelist(self):
        """Test that _parse_matcher calls _parse_matcher_in_segment on WHITELIST matcher"""
        matcher = self._get_matcher('WHITELIST')
        self.parser._parse_matcher(self.some_partial_split, matcher)
        self.parse_matcher_whitelist_mock.assert_called_once_with(
            self.some_partial_split, matcher, block_until_ready=False)

    def test_calls_parse_matcher_equal_to(self):
        """Test that _parse_matcher calls _parse_matcher_equal_to on EQUAL_TO matcher"""
        matcher = self._get_matcher('EQUAL_TO')
        self.parser._parse_matcher(self.some_partial_split, matcher)
        self.parse_matcher_equal_to_mock.assert_called_once_with(
            self.some_partial_split, matcher, block_until_ready=False)

    def test_calls_parse_matcher_greater_than_or_equal_to(self):
        """
        Test that _parse_matcher calls _parse_matcher_greater_than_or_equal_to on
        GREATER_THAN_OR_EQUAL_TO matcher
        """
        matcher = self._get_matcher('GREATER_THAN_OR_EQUAL_TO')
        self.parser._parse_matcher(self.some_partial_split, matcher)
        self.parse_matcher_greater_than_or_equal_to_mock.assert_called_once_with(
            self.some_partial_split, matcher, block_until_ready=False)

    def test_calls_parse_matcher_less_than_or_equal_to(self):
        """
        Test that _parse_matcher calls _parse_matcher_less_than_or_equal_to on
        LESS_THAN_OR_EQUAL_TO matcher
        """
        matcher = self._get_matcher('LESS_THAN_OR_EQUAL_TO')
        self.parser._parse_matcher(self.some_partial_split, matcher)
        self.parse_matcher_less_than_or_equal_to_mock.assert_called_once_with(
            self.some_partial_split, matcher, block_until_ready=False)

    def test_calls_parse_matcher_between(self):
        """Test that _parse_matcher calls _parse_between on BETWEEN matcher"""
        matcher = self._get_matcher('BETWEEN')
        self.parser._parse_matcher(self.some_partial_split, matcher)
        self.parse_matcher_between_mock.assert_called_once_with(
            self.some_partial_split, matcher, block_until_ready=False)

    def test_raises_exception_if_parse_method_returns_none(self):
        """
        Tests that _parse_matcher raises an exception if the specific parse method returns None
        """
        self.parser._parse_matcher_fake.return_value = None
        with self.assertRaises(ValueError):
            self.parser._parse_matcher(self.some_partial_split,
                                       self._get_matcher('FAKE'))

    def test_returns_attribute_matcher(self):
        """Tests that _parse_matcher returns an AttributeMatcher"""
        self.assertIsInstance(
            self.parser._parse_matcher(self.some_partial_split,
                                       self._get_matcher('FAKE')),
            AttributeMatcher)
class SplitParserInternalParseTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self.some_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()
        self.some_block_until_ready = mock.MagicMock()

        self.partition_mock = self.patch('splitio.splits.Partition')
        self.partition_mock_side_effect = [mock.MagicMock() for _ in range(3)]
        self.partition_mock.side_effect = self.partition_mock_side_effect

        self.condition_mock = self.patch('splitio.splits.Condition')
        self.condition_mock_side_effect = [mock.MagicMock() for _ in range(2)]
        self.condition_mock.side_effect = self.condition_mock_side_effect

        self.parser = SplitParser(self.some_segment_fetcher)
        self.parse_split_mock = self.patch_object(self.parser, '_parse_split')
        self.parse_matcher_group_mock = self.patch_object(
            self.parser, '_parse_matcher_group')
        self.parse_matcher_group_mock_side_effect = [
            mock.MagicMock() for _ in range(2)
        ]
        self.parse_matcher_group_mock.side_effect = self.parse_matcher_group_mock_side_effect

        self.partition_0 = {
            'treatment': mock.MagicMock(),
            'size': mock.MagicMock()
        }
        self.partition_1 = {
            'treatment': mock.MagicMock(),
            'size': mock.MagicMock()
        }
        self.partition_2 = {
            'treatment': mock.MagicMock(),
            'size': mock.MagicMock()
        }

        self.matcher_group_0 = mock.MagicMock()
        self.matcher_group_1 = mock.MagicMock()

        self.label_0 = mock.MagicMock()
        self.label_1 = mock.MagicMock()

        self.some_split = {
            'status':
            'ACTIVE',
            'name':
            mock.MagicMock(),
            'seed':
            mock.MagicMock(),
            'killed':
            mock.MagicMock(),
            'defaultTreatment':
            mock.MagicMock(),
            'conditions': [{
                'matcherGroup': self.matcher_group_0,
                'partitions': [self.partition_0],
                'label': self.label_0
            }, {
                'matcherGroup': self.matcher_group_1,
                'partitions': [self.partition_1, self.partition_2],
                'label': self.label_1
            }]
        }

    def test_returns_none_if_status_is_not_active(self):
        """Tests that _parse returns None if split is not ACTIVE"""
        self.assertIsNone(self.parser._parse({'status': 'ARCHIVED'}))

    def test_creates_partition_on_each_condition_partition(self):
        """Test that _parse calls Partition constructor on each partition"""
        self.parser._parse(self.some_split)

        self.assertListEqual([
            mock.call(self.partition_0['treatment'], self.partition_0['size']),
            mock.call(self.partition_1['treatment'], self.partition_1['size']),
            mock.call(self.partition_2['treatment'], self.partition_2['size'])
        ], self.partition_mock.call_args_list)

    def test_calls_parse_matcher_group_on_each_matcher_group(self):
        """Tests that _parse calls _parse_matcher_group on each matcher group with the default
        value for block_until_ready"""
        self.parser._parse(self.some_split)

        self.assertListEqual([
            mock.call(self.parse_split_mock.return_value,
                      self.matcher_group_0,
                      block_until_ready=False),
            mock.call(self.parse_split_mock.return_value,
                      self.matcher_group_1,
                      block_until_ready=False)
        ], self.parse_matcher_group_mock.call_args_list)

    def test_calls_parse_matcher_group_on_each_matcher_group_with_block_until_ready(
            self):
        """Tests that _parse calls _parse_matcher_group on each matcher group with the passed
        value for block_until_ready"""
        some_block_until_ready = mock.MagicMock()
        self.parser._parse(self.some_split,
                           block_until_ready=some_block_until_ready)

        self.assertListEqual([
            mock.call(self.parse_split_mock.return_value,
                      self.matcher_group_0,
                      block_until_ready=some_block_until_ready),
            mock.call(self.parse_split_mock.return_value,
                      self.matcher_group_1,
                      block_until_ready=some_block_until_ready)
        ], self.parse_matcher_group_mock.call_args_list)

    def test_creates_condition_on_each_condition(self):
        """Tests that _parse calls Condition constructor on each condition"""
        self.parser._parse(self.some_split)

        self.assertListEqual([
            mock.call(self.parse_matcher_group_mock_side_effect[0],
                      [self.partition_mock_side_effect[0]], self.label_0,
                      ConditionType.WHITELIST),
            mock.call(self.parse_matcher_group_mock_side_effect[1], [
                self.partition_mock_side_effect[1],
                self.partition_mock_side_effect[2]
            ], self.label_1, ConditionType.WHITELIST)
        ], self.condition_mock.call_args_list)

    def test_calls_parse_split(self):
        """Tests that _parse calls _parse_split"""
        self.parser._parse(self.some_split,
                           block_until_ready=self.some_block_until_ready)

        self.parse_split_mock.assert_called_once_with(
            self.some_split, block_until_ready=self.some_block_until_ready)
class SplitParserMatcherParseMethodsTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self.some_partial_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()
        self.some_matcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)

        self.get_matcher_data_data_type_mock = self.patch_object(
            self.parser, '_get_matcher_data_data_type')
        self.equal_to_matcher_mock = self.patch(
            'splitio.splits.EqualToMatcher')
        self.greater_than_or_equal_to_matcher_mock = self.patch(
            'splitio.splits.GreaterThanOrEqualToMatcher')
        self.less_than_or_equal_to_matcher_mock = self.patch(
            'splitio.splits.LessThanOrEqualToMatcher')
        self.between_matcher_mock = self.patch('splitio.splits.BetweenMatcher')

        self.some_in_segment_matcher = {
            'matcherType': 'IN_SEGMENT',
            'userDefinedSegmentMatcherData': {
                'segmentName': mock.MagicMock()
            }
        }
        self.some_whitelist_matcher = {
            'matcherType': 'WHITELIST',
            'whitelistMatcherData': {
                'whitelist': mock.MagicMock()
            }
        }
        self.some_equal_to_matcher = self._get_unary_number_matcher('EQUAL_TO')
        self.some_greater_than_or_equal_to_matcher = self._get_unary_number_matcher(
            'GREATER_THAN_OR_EQUAL_TO')
        self.some_less_than_or_equal_to_matcher = self._get_unary_number_matcher(
            'LESS_THAN_OR_EQUAL_TO')
        self.some_between_matcher = {
            'matcherType': 'BETWEEN',
            'betweenMatcherData': {
                'start': mock.MagicMock(),
                'end': mock.MagicMock(),
            }
        }

    def _get_unary_number_matcher(self, matcher_type):
        return {
            'matcherType': matcher_type,
            'unaryNumericMatcherData': {
                'dataType': mock.MagicMock(),
                'value': mock.MagicMock()
            }
        }

    def test_parse_matcher_all_keys_returns_all_keys_matcher(self):
        """Tests that _parser_matcher_all_keys returns an AllKeysMatcher"""
        self.assertIsInstance(
            self.parser._parse_matcher_all_keys(self.some_partial_split,
                                                self.some_matcher),
            AllKeysMatcher)

    def test_parse_matcher_in_segment_calls_segment_fetcher_fetch(self):
        """Tests that _parse_matcher_in_segment calls segment_fetcher fetch method with default
        value for block_until_ready"""
        self.parser._parse_matcher_in_segment(self.some_partial_split,
                                              self.some_in_segment_matcher)
        self.some_segment_fetcher.fetch.assert_called_once_with(
            self.some_in_segment_matcher['userDefinedSegmentMatcherData']
            ['segmentName'],
            block_until_ready=False)

    def test_parse_matcher_in_segment_calls_segment_fetcher_fetch_block(self):
        """Tests that _parse_matcher_in_segment calls segment_fetcher fetch method with supploed
        value for block_until_ready"""
        some_block_until_ready = mock.MagicMock()
        self.parser._parse_matcher_in_segment(
            self.some_partial_split,
            self.some_in_segment_matcher,
            block_until_ready=some_block_until_ready)
        self.some_segment_fetcher.fetch.assert_called_once_with(
            self.some_in_segment_matcher['userDefinedSegmentMatcherData']
            ['segmentName'],
            block_until_ready=some_block_until_ready)

    def test_parse_matcher_in_segment_returns_user_defined_segment_matcher(
            self):
        """Tests that _parse_matcher_in_segment calls segment_fetcher fetch method"""
        self.assertIsInstance(
            self.parser._parse_matcher_in_segment(
                self.some_partial_split, self.some_in_segment_matcher),
            UserDefinedSegmentMatcher)

    def test_parse_matcher_whitelist_returns_whitelist_matcher(self):
        """Tests that _parse_matcher_whitelist returns a WhitelistMatcher"""
        self.assertIsInstance(
            self.parser._parse_matcher_whitelist(self.some_partial_split,
                                                 self.some_whitelist_matcher),
            WhitelistMatcher)

    def test_parse_matcher_equal_to_calls_equal_to_matcher_for_data_type(self):
        """Tests that _parse_matcher_equal_to calls EqualToMatcher.for_data_type"""
        self.parser._parse_matcher_equal_to(self.some_partial_split,
                                            self.some_equal_to_matcher)
        self.equal_to_matcher_mock.for_data_type.assert_called_once_with(
            self.get_matcher_data_data_type_mock.return_value,
            self.some_equal_to_matcher['unaryNumericMatcherData']['value'])

    def test_parse_matcher_equal_to_returns_equal_to_matcher(self):
        """
        Tests that _parse_matcher_equal_to returns the result of calling
        EqualToMatcher.for_data_type
        """
        self.assertEqual(
            self.equal_to_matcher_mock.for_data_type.return_value,
            self.parser._parse_matcher_equal_to(self.some_partial_split,
                                                self.some_equal_to_matcher))

    def test_parse_matcher_greater_than_or_equal_to_calls_equal_to_matcher_for_data_type(
            self):
        """
        Tests that _parse_matcher_greater_than_or_equal_to calls
        GreaterThanOrEqualToMatcher.for_data_type
        """
        self.parser._parse_matcher_greater_than_or_equal_to(
            self.some_partial_split,
            self.some_greater_than_or_equal_to_matcher)
        self.greater_than_or_equal_to_matcher_mock.for_data_type.assert_called_once_with(
            self.get_matcher_data_data_type_mock.return_value,
            self.some_greater_than_or_equal_to_matcher[
                'unaryNumericMatcherData']['value'])

    def test_parse_matcher_greater_than_or_equal_to_returns_equal_to_matcher(
            self):
        """
        Tests that _parse_matcher_greater_than_or_equal_to returns the result of calling
        GreaterThanOrEqualToMatcher.for_data_type
        """
        self.assertEqual(
            self.greater_than_or_equal_to_matcher_mock.for_data_type.
            return_value,
            self.parser._parse_matcher_greater_than_or_equal_to(
                self.some_partial_split,
                self.some_greater_than_or_equal_to_matcher))

    def test_parse_matcher_less_than_or_equal_to_calls_equal_to_matcher_for_data_type(
            self):
        """
        Tests that _parse_matcher_less_than_or_equal_to calls
        LessThanOrEqualToMatcher.for_data_type
        """
        self.parser._parse_matcher_less_than_or_equal_to(
            self.some_partial_split, self.some_less_than_or_equal_to_matcher)
        self.less_than_or_equal_to_matcher_mock.for_data_type.assert_called_once_with(
            self.get_matcher_data_data_type_mock.return_value,
            self.some_less_than_or_equal_to_matcher['unaryNumericMatcherData']
            ['value'])

    def test_parse_matcher_less_than_or_equal_to_returns_equal_to_matcher(
            self):
        """
        Tests that _parse_matcher_less_than_or_equal_to returns the result of calling
        LessThanOrEqualToMatcher.for_data_type
        """
        self.assertEqual(
            self.less_than_or_equal_to_matcher_mock.for_data_type.return_value,
            self.parser._parse_matcher_less_than_or_equal_to(
                self.some_partial_split,
                self.some_less_than_or_equal_to_matcher))

    def test_parse_matcher_between_calls_between_matcher_for_data_type(self):
        """Tests that _parse_matcher_between calls BetweenMatcher.for_data_type"""
        self.parser._parse_matcher_between(self.some_partial_split,
                                           self.some_between_matcher)
        self.between_matcher_mock.for_data_type.assert_called_once_with(
            self.get_matcher_data_data_type_mock.return_value,
            self.some_between_matcher['betweenMatcherData']['start'],
            self.some_between_matcher['betweenMatcherData']['end'])

    def test_parse_matcher_between_returns_between_matcher(self):
        """
        Tests that _parse_matcher_between returns the result of calling
        BetweenMatcher.for_data_type
        """
        self.assertEqual(
            self.between_matcher_mock.for_data_type.return_value,
            self.parser._parse_matcher_between(self.some_partial_split,
                                               self.some_between_matcher))
    def setUp(self):
        self.some_segment_fetcher = mock.MagicMock()

        self.parser = SplitParser(self.some_segment_fetcher)
    def setUp(self):
        self.some_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()
        self.some_block_until_ready = mock.MagicMock()

        self.partition_mock = self.patch('splitio.splits.Partition')
        self.partition_mock_side_effect = [mock.MagicMock() for _ in range(3)]
        self.partition_mock.side_effect = self.partition_mock_side_effect

        self.condition_mock = self.patch('splitio.splits.Condition')
        self.condition_mock_side_effect = [mock.MagicMock() for _ in range(2)]
        self.condition_mock.side_effect = self.condition_mock_side_effect

        self.parser = SplitParser(self.some_segment_fetcher)
        self.parse_split_mock = self.patch_object(self.parser, '_parse_split')
        self.parse_matcher_group_mock = self.patch_object(
            self.parser, '_parse_matcher_group')
        self.parse_matcher_group_mock_side_effect = [
            mock.MagicMock() for _ in range(2)
        ]
        self.parse_matcher_group_mock.side_effect = self.parse_matcher_group_mock_side_effect

        self.partition_0 = {
            'treatment': mock.MagicMock(),
            'size': mock.MagicMock()
        }
        self.partition_1 = {
            'treatment': mock.MagicMock(),
            'size': mock.MagicMock()
        }
        self.partition_2 = {
            'treatment': mock.MagicMock(),
            'size': mock.MagicMock()
        }

        self.matcher_group_0 = mock.MagicMock()
        self.matcher_group_1 = mock.MagicMock()

        self.label_0 = mock.MagicMock()
        self.label_1 = mock.MagicMock()

        self.some_split = {
            'status':
            'ACTIVE',
            'name':
            mock.MagicMock(),
            'seed':
            mock.MagicMock(),
            'killed':
            mock.MagicMock(),
            'defaultTreatment':
            mock.MagicMock(),
            'conditions': [{
                'matcherGroup': self.matcher_group_0,
                'partitions': [self.partition_0],
                'label': self.label_0
            }, {
                'matcherGroup': self.matcher_group_1,
                'partitions': [self.partition_1, self.partition_2],
                'label': self.label_1
            }]
        }
class SplitParserParseMatcherGroupTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self.some_partial_split = mock.MagicMock()
        self.some_segment_fetcher = mock.MagicMock()

        self.combining_matcher_mock = self.patch(
            'splitio.splits.CombiningMatcher')
        self.parser = SplitParser(self.some_segment_fetcher)
        self.parse_matcher_mock = self.patch_object(self.parser,
                                                    '_parse_matcher')
        self.parse_matcher_side_effect = [mock.MagicMock() for _ in range(2)]
        self.parse_matcher_mock.side_effect = self.parse_matcher_side_effect
        self.parse_combiner_mock = self.patch_object(self.parser,
                                                     '_parse_combiner')

        self.some_matchers = [mock.MagicMock(), mock.MagicMock()]
        self.some_matcher_group = {
            'matchers': self.some_matchers,
            'combiner': mock.MagicMock()
        }

    def test_calls_parse_matcher_on_each_matcher(self):
        """Tests that _parse_matcher_group calls _parse_matcher on each matcher with the default
        value for block_until_ready"""
        self.parser._parse_matcher_group(self.some_partial_split,
                                         self.some_matcher_group)
        self.assertListEqual([
            mock.call(self.some_partial_split,
                      self.some_matchers[0],
                      block_until_ready=False),
            mock.call(self.some_partial_split,
                      self.some_matchers[1],
                      block_until_ready=False)
        ], self.parse_matcher_mock.call_args_list)

    def test_calls_parse_matcher_with_block_until_ready_parameter(self):
        """Tests that _parse_matcher_group calls _parse_matcher on each matcher"""
        some_block_until_ready = mock.MagicMock
        self.parser._parse_matcher_group(
            self.some_partial_split,
            self.some_matcher_group,
            block_until_ready=some_block_until_ready)
        self.assertListEqual([
            mock.call(self.some_partial_split,
                      self.some_matchers[0],
                      block_until_ready=some_block_until_ready),
            mock.call(self.some_partial_split,
                      self.some_matchers[1],
                      block_until_ready=some_block_until_ready)
        ], self.parse_matcher_mock.call_args_list)

    def test_calls_parse_combiner_on_combiner(self):
        """Tests that _parse_matcher_group calls _parse_combiner on combiner"""
        self.parser._parse_matcher_group(self.some_partial_split,
                                         self.some_matcher_group)
        self.parse_combiner_mock.assert_called_once_with(
            self.some_matcher_group['combiner'])

    def test_creates_combining_matcher(self):
        """Tests that _parse_matcher_group calls CombiningMatcher constructor"""
        self.parser._parse_matcher_group(self.some_partial_split,
                                         self.some_matcher_group)
        self.combining_matcher_mock.assert_called_once_with(
            self.parse_combiner_mock.return_value,
            self.parse_matcher_side_effect)

    def test_returns_combining_matcher(self):
        """Tests that _parse_matcher_group returns a CombiningMatcher"""
        self.assertEqual(
            self.combining_matcher_mock.return_value,
            self.parser._parse_matcher_group(self.some_partial_split,
                                             self.some_matcher_group))