"""
Unit tests for the result of calling see() with various types of object.

"""
import itertools
import unittest

from see import see


def union(*sets):
    return set(itertools.chain(*sets))


SIGN_OPS = set(['+obj', '-obj'])

NUMBER_OPS = set('+ - * / // % **'.split())
NUMBER_ASSIGN_OPS = set()

BITWISE_OPS = set('<< >> & ^ | ~'.split())
BITWISE_ASSIGN_OPS = set(op + '=' for op in BITWISE_OPS)

COMPARE_OPS = set('< <= == != > >='.split())

MATRIX_OPS = set(['@'])
MATRIX_ASSIGN_OPS = set(['@='])

ALL_OPS = union(
    SIGN_OPS,
    NUMBER_OPS,
    NUMBER_ASSIGN_OPS,
    BITWISE_OPS,
    BITWISE_ASSIGN_OPS,
    COMPARE_OPS,
    MATRIX_OPS,
    MATRIX_ASSIGN_OPS,
)


class TestSeeResult(unittest.TestCase):

    def check_ops(self, obj_type, expected_ops, see_output):
        for op in ALL_OPS:
            if op in expected_ops:
                self.assertIn(
                    op, see_output,
                    'expected %s to support %s' % (obj_type, op))
            else:
                self.assertNotIn(
                    op, see_output,
                    'expected %s not to support %s' % (obj_type, op))

    def test_int(self):
        obj = 1
        lit_ops = union(
            SIGN_OPS,
            NUMBER_OPS,
            BITWISE_OPS,
            COMPARE_OPS,
        )
        obj_ops = union(
            lit_ops,
        )

        lit_see = see(1)
        obj_see = see(obj)

        self.check_ops('int literal', lit_ops, lit_see)
        self.check_ops('int object', obj_ops, obj_see)

    def test_float(self):
        obj = 1.0
        lit_ops = union(
            SIGN_OPS,
            NUMBER_OPS,
            COMPARE_OPS,
        )
        obj_ops = union(
            lit_ops,
        )

        lit_see = see(1.0)
        obj_see = see(obj)

        self.check_ops('float literal', lit_ops, lit_see)
        self.check_ops('float object', obj_ops, obj_see)

    def test_isfunction(self):

        def a_function():
            pass

        output = see(a_function)

        self.assertIn('isfunction', output)
        self.assertIn('()', output)

@@ -201,21 +201,17 @@
 N_OPS = 
-set(%5B
+%7B
 '+obj', 
@@ -216,18 +216,17 @@
 , '-obj'
-%5D)
+%7D
 %0A%0ANUMBER
@@ -454,18 +454,13 @@
 S = 
-set(%5B'@'%5D)
+%7B'@'%7D
 %0AMAT
@@ -480,19 +480,14 @@
 S = 
-set(%5B
+%7B
 '@='
-%5D)
+%7D
 %0A%0AAL

Rewrite unnecessary list literal as set literal