<filename>tests/test_issues.py
import os
import io
from unittest import TestCase
from py_linq import Enumerable
from tests import _empty, _simple, _complex
from py_linq import exceptions


class IssueTests(TestCase):
    def setUp(self):
        self.empty = Enumerable(_empty)
        self.simple = Enumerable(_simple)
        self.complex = Enumerable(_complex)

    def test_issue19_1(self):
        foo = Enumerable([1])
        bar = Enumerable([1])
        self.assertEqual(foo.intersect(bar).count(), 1)

    def test_issue19_2(self):
        foo = Enumerable([1])
        bar = Enumerable([1]).distinct()
        self.assertEqual(foo.intersect(bar).count(), 1)

    def test_issue19_3(self):
        foo = Enumerable([1]).distinct()
        bar = Enumerable([1])
        self.assertEqual(foo.intersect(bar).count(), 1)

    def test_issue22(self):
        def my_iter():
            for i in range(10):
                yield i

        def low_iter():
            for i in range(5):
                yield i

        def high_iter():
            for k in range(5):
                yield k + 5

        data = my_iter()
        a = Enumerable(data)

        low = a.where(lambda x: x < 5)
        high = a.where(lambda x: x >= 5)

        self.assertListEqual(
            [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)], low.zip(high).to_list()
        )

        self.assertListEqual(
            [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)], list(zip(low, high))
        )

    def test_generator_to_Enumerable(self):
        def first_3():
            for i in range(3):
                yield i

        p2 = Enumerable(first_3())
        self.assertListEqual([0, 1, 2], p2.to_list())

        p3 = Enumerable((i for i in first_3()))
        self.assertListEqual([0, 1, 2], p3.to_list())

    def test_issue22_join(self):
        class Val(object):
            def __init__(self, number, power):
                self.number = number
                self.power = power

            def __str__(self):
                return "VAL {0}: {1}".format(self.number, self.power)

        def powers_of_2():
            for i in range(2):
                yield Val(i, 2 ** i)

        def powers_of_10():
            for i in range(2):
                yield Val(i, 10 ** i)

        en2 = Enumerable(powers_of_2())
        en10 = Enumerable(powers_of_10())
        joined = en2.join(
            en10,
            lambda x: x.number,
            lambda y: y.number,
            lambda r: (r[0].power, r[1].power),
        )
        truth = zip([2 ** i for i in range(2)], [10 ** y for y in range(2)])
        self.assertListEqual(list(truth), joined.to_list())

    def test_first_with_lambda(self):
        self.assertRaises(IndexError, self.empty.first, lambda x: x == 0)
        self.assertEqual(2, self.simple.first(lambda x: x == 2))
        self.assertDictEqual(
            {"value": 2}, self.complex.first(lambda x: x["value"] == 2)
        )

    def test_first_or_default_with_lambda(self):
        self.assertIsNone(self.empty.first_or_default(lambda x: x == 0))
        self.assertEqual(
            self.simple.first(lambda x: x == 2),
            self.simple.first_or_default(lambda x: x == 2),
        )
        self.assertEqual(
            self.complex.first(lambda x: x["value"] == 2),
            self.complex.first_or_default(lambda x: x["value"] == 2),
        )

    def test_last_with_lambda(self):
        self.assertRaises(IndexError, self.empty.last, lambda x: x == 0)
        self.assertEqual(2, self.simple.last(lambda x: x == 2))
        self.assertDictEqual({"value": 2}, self.complex.last(lambda x: x["value"] == 2))
        self.assertEqual(
            self.simple.first(lambda x: x == 2), self.simple.last(lambda x: x == 2)
        )

    def test_last_or_default_with_lambda(self):
        self.assertIsNone(self.empty.last_or_default(lambda x: x == 0))
        self.assertEqual(
            self.simple.last(lambda x: x == 2),
            self.simple.last_or_default(lambda x: x == 2),
        )
        self.assertEqual(
            self.complex.last(lambda x: x["value"] == 2),
            self.complex.last_or_default(lambda x: x["value"] == 2),
        )
        self.assertEqual(
            self.simple.first_or_default(lambda x: x == 2),
            self.simple.last_or_default(lambda x: x == 2),
        )

    def test_issue_34(self):
        class Obj(object):
            def __init__(self, n, v):
                self.n = n
                self.v = v

        foo = Enumerable([Obj("foo", 1), Obj("bar", 2)])
        self.assertTrue(foo.any(lambda x: x.n == "foo"))
        self.assertTrue(foo.any(lambda x: x.n == "foo"))
        filtered_foo = foo.where(lambda x: x.n == "foo")
        self.assertIsNotNone(filtered_foo.first())
        self.assertEqual("foo", filtered_foo.first().n)
        self.assertTrue(filtered_foo.any(lambda x: x.v == 1))
        self.assertTrue(filtered_foo.any(lambda x: x.v == 1))

    def test_issue_35(self):
        a = Enumerable([9, 8, -7, 6, 5])
        b = a.order_by(lambda x: x)
        self.assertEqual(-7, b.first())
        self.assertEqual(-7, list(b)[0])
        self.assertEqual(-7, b.first())

    def test_issue_36(self):
        def append_to_list(lst, element):
            lst.append(element)

        filepath = os.path.join(os.getcwd(), "tests", "files", "test_file1.txt")
        result = []
        with io.open(filepath) as f:
            lines = (
                Enumerable(f)
                .skip(1)
                .where(lambda l: not l.startswith("#"))
                .aggregate(append_to_list, result)
            )
        self.assertEqual(1, len(result))
        self.assertEqual("This line should be counted", result[0])

    def test_issue_47(self):
        marks = Enumerable([(25,'a'), (49,'b'), (50,'c'), (80,'d'), (90,'e')])
        passing = marks.where(lambda x: x[0] >= 50)
        self.assertListEqual([(50, 'c'), (80, 'd'), (90, 'e')], passing.to_list())
        omarks = Enumerable([(80,'eighty'),(49,'fortynine')])
        join_result = omarks.join(passing, lambda o:o[0], lambda y:y[0], lambda result: result).to_list()
        self.assertListEqual([((80, 'eighty'), (80, 'd'))], join_result)

    def test_empty_join(self):
        marks = Enumerable([(25,'a'), (49,'b'), (50,'c'), (80,'d'), (90,'e')])
        passing = marks.where(lambda x: x[0] > 90)
        self.assertListEqual([], passing.to_list())
        omarks = Enumerable([(80,'eighty'),(49,'fortynine')])
        join_result = omarks.join(passing, lambda o:o[0], lambda y:y[0], lambda result: result).to_list()
        self.assertListEqual([], join_result)

    def test_issue_50(self):
        """
        Only single char for key value on group_by
        """
        class MyObject(object):
            def __init__(self, name):
                self.field = name
                
            def get_field(self):
                return self.field

        test = Enumerable([MyObject("Bruce"), MyObject("Bruce"), MyObject("Fenske"), MyObject("Luke")])
        group = test.group_by(key_names=['field_name'], key=lambda r: r.get_field()) \
            .order_by(lambda g: g.key.field_name)
        self.assertEqual("Bruce", group[0].key.field_name)

    def test_issue_50_2(self):
        class MyObject(object):
            def __init__(self, name):
                self.field = name
                
            def get_field(self):
                return self.field

        def get_field(item):
            return item.get_field()

        test = Enumerable([MyObject("Bruce"), MyObject("Bruce"), MyObject("Fenske"), MyObject("Luke")])
        group = test.group_by(key_names=['field_name'], key=get_field).order_by(lambda g: g.key.field_name)
        self.assertEqual("Bruce", group[0].key.field_name)




<filename>tests/test_issues.py
import os
import io
from unittest import TestCase
from py_linq import Enumerable
from tests import _empty, _simple, _complex
from py_linq import exceptions


class IssueTests(TestCase):
    def setUp(self):
        self.empty = Enumerable(_empty)
        self.simple = Enumerable(_simple)
        self.complex = Enumerable(_complex)

    def test_issue19_1(self):
        foo = Enumerable([1])
        bar = Enumerable([1])
        self.assertEqual(foo.intersect(bar).count(), 1)

    def test_issue19_2(self):
        foo = Enumerable([1])
        bar = Enumerable([1]).distinct()
        self.assertEqual(foo.intersect(bar).count(), 1)

    def test_issue19_3(self):
        foo = Enumerable([1]).distinct()
        bar = Enumerable([1])
        self.assertEqual(foo.intersect(bar).count(), 1)

    def test_issue22(self):
        def my_iter():
            for i in range(10):
                yield i

        def low_iter():
            for i in range(5):
                yield i

        def high_iter():
            for k in range(5):
                yield k + 5

        data = my_iter()
        a = Enumerable(data)

        low = a.where(lambda x: x < 5)
        high = a.where(lambda x: x >= 5)

        self.assertListEqual(
            [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)], low.zip(high).to_list()
        )

        self.assertListEqual(
            [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)], list(zip(low, high))
        )

    def test_generator_to_Enumerable(self):
        def first_3():
            for i in range(3):
                yield i

        p2 = Enumerable(first_3())
        self.assertListEqual([0, 1, 2], p2.to_list())

        p3 = Enumerable((i for i in first_3()))
        self.assertListEqual([0, 1, 2], p3.to_list())

    def test_issue22_join(self):
        class Val(object):
            def __init__(self, number, power):
                self.number = number
                self.power = power

            def __str__(self):
                return "VAL {0}: {1}".format(self.number, self.power)

        def powers_of_2():
            for i in range(2):
                yield Val(i, 2 ** i)

        def powers_of_10():
            for i in range(2):
                yield Val(i, 10 ** i)

        en2 = Enumerable(powers_of_2())
        en10 = Enumerable(powers_of_10())
        joined = en2.join(
            en10,
            lambda x: x.number,
            lambda y: y.number,
            lambda r: (r[0].power, r[1].power),
        )
        truth = zip([2 ** i for i in range(2)], [10 ** y for y in range(2)])
        self.assertListEqual(list(truth), joined.to_list())

    def test_first_with_lambda(self):
        self.assertRaises(IndexError, self.empty.first, lambda x: x == 0)
        self.assertEqual(2, self.simple.first(lambda x: x == 2))
        self.assertDictEqual(
            {"value": 2}, self.complex.first(lambda x: x["value"] == 2)
        )

    def test_first_or_default_with_lambda(self):
        self.assertIsNone(self.empty.first_or_default(lambda x: x == 0))
        self.assertEqual(
            self.simple.first(lambda x: x == 2),
            self.simple.first_or_default(lambda x: x == 2),
        )
        self.assertEqual(
            self.complex.first(lambda x: x["value"] == 2),
            self.complex.first_or_default(lambda x: x["value"] == 2),
        )

    def test_last_with_lambda(self):
        self.assertRaises(IndexError, self.empty.last, lambda x: x == 0)
        self.assertEqual(2, self.simple.last(lambda x: x == 2))
        self.assertDictEqual({"value": 2}, self.complex.last(lambda x: x["value"] == 2))
        self.assertEqual(
            self.simple.first(lambda x: x == 2), self.simple.last(lambda x: x == 2)
        )

    def test_last_or_default_with_lambda(self):
        self.assertIsNone(self.empty.last_or_default(lambda x: x == 0))
        self.assertEqual(
            self.simple.last(lambda x: x == 2),
            self.simple.last_or_default(lambda x: x == 2),
        )
        self.assertEqual(
            self.complex.last(lambda x: x["value"] == 2),
            self.complex.last_or_default(lambda x: x["value"] == 2),
        )
        self.assertEqual(
            self.simple.first_or_default(lambda x: x == 2),
            self.simple.last_or_default(lambda x: x == 2),
        )

    def test_issue_34(self):
        class Obj(object):
            def __init__(self, n, v):
                self.n = n
                self.v = v

        foo = Enumerable([Obj("foo", 1), Obj("bar", 2)])
        self.assertTrue(foo.any(lambda x: x.n == "foo"))
        self.assertTrue(foo.any(lambda x: x.n == "foo"))
        filtered_foo = foo.where(lambda x: x.n == "foo")
        self.assertIsNotNone(filtered_foo.first())
        self.assertEqual("foo", filtered_foo.first().n)
        self.assertTrue(filtered_foo.any(lambda x: x.v == 1))
        self.assertTrue(filtered_foo.any(lambda x: x.v == 1))

    def test_issue_35(self):
        a = Enumerable([9, 8, -7, 6, 5])
        b = a.order_by(lambda x: x)
        self.assertEqual(-7, b.first())
        self.assertEqual(-7, list(b)[0])
        self.assertEqual(-7, b.first())

    def test_issue_36(self):
        def append_to_list(lst, element):
            lst.append(element)

        filepath = os.path.join(os.getcwd(), "tests", "files", "test_file1.txt")
        result = []
        with io.open(filepath) as f:
            lines = (
                Enumerable(f)
                .skip(1)
                .where(lambda l: not l.startswith("#"))
                .aggregate(append_to_list, result)
            )
        self.assertEqual(1, len(result))
        self.assertEqual("This line should be counted", result[0])

    def test_issue_47(self):
        marks = Enumerable([(25,'a'), (49,'b'), (50,'c'), (80,'d'), (90,'e')])
        passing = marks.where(lambda x: x[0] >= 50)
        self.assertListEqual([(50, 'c'), (80, 'd'), (90, 'e')], passing.to_list())
        omarks = Enumerable([(80,'eighty'),(49,'fortynine')])
        join_result = omarks.join(passing, lambda o:o[0], lambda y:y[0], lambda result: result).to_list()
        self.assertListEqual([((80, 'eighty'), (80, 'd'))], join_result)

    def test_empty_join(self):
        marks = Enumerable([(25,'a'), (49,'b'), (50,'c'), (80,'d'), (90,'e')])
        passing = marks.where(lambda x: x[0] > 90)
        self.assertListEqual([], passing.to_list())
        omarks = Enumerable([(80,'eighty'),(49,'fortynine')])
        join_result = omarks.join(passing, lambda o:o[0], lambda y:y[0], lambda result: result).to_list()
        self.assertListEqual([], join_result)

    def test_issue_50(self):
        """
        Only single char for key value on group_by
        """
        class MyObject(object):
            def __init__(self, name):
                self.field = name
                
            def get_field(self):
                return self.field

        test = Enumerable([MyObject("Bruce"), MyObject("Bruce"), MyObject("Fenske"), MyObject("Luke")])
        group = test.group_by(key_names=['field_name'], key=lambda r: r.get_field()) \
            .order_by(lambda g: g.key.field_name)
        self.assertEqual("Bruce", group[0].key.field_name)

    def test_issue_50_2(self):
        class MyObject(object):
            def __init__(self, name):
                self.field = name
                
            def get_field(self):
                return self.field

        def get_field(item):
            return item.get_field()

        test = Enumerable([MyObject("Bruce"), MyObject("Bruce"), MyObject("Fenske"), MyObject("Luke")])
        group = test.group_by(key_names=['field_name'], key=get_field).order_by(lambda g: g.key.field_name)
        self.assertEqual("Bruce", group[0].key.field_name)




Only single char for key value on group_by