import unittest

from pkg_resources import resource_string
from .. import parse, parser


class LambdaSupportTest(unittest.TestCase):
    """ Contains tests for java 8 lambda syntax. """

    def _class_template(self, content_to_add):
        """ returns an example java class with the
            given content_to_add contained within a method.
        """
        template = """
public class Lambda {

    public static void main(String args[]) {
        %s
    }
}
        """
        return template % content_to_add

    def test_lambda_support_no_parameters_no_body(self):
        """ tests support for lambda with no parameters and no body. """
        parse.parse(self._class_template("() -> {};"))

    def test_lambda_support_no_parameters_expression_body(self):
        """ tests support for lambda with no parameters and an
            expression body.
        """
        parse.parse(self._class_template("() -> 3;"))
        parse.parse(self._class_template("() -> null;"))
        parse.parse(self._class_template("() -> { return 21; };"))
        parse.parse(self._class_template("() -> { System.exit(1); };"))

    def test_lambda_support_no_parameters_complex_expression(self):
        """ tests support for lambda with no parameters and a
            complex expression body.
        """
        code = """
                () -> {
            if (true) return 21;
            else
            {
                int result = 21;
                return result / 2;
            }
        };"""
        parse.parse(self._class_template(code))

    def test_parameter_no_type_expression_body(self):
        """ tests support for lambda with parameters with inferred types. """
        parse.parse(self._class_template("(bar) -> bar + 1;"))
        parse.parse(self._class_template("bar -> bar + 1;"))
        parse.parse(self._class_template("x -> x.length();"))
        parse.parse(self._class_template("y -> { y.boom(); };"))

    def test_parameter_with_type_expression_body(self):
        """ tests support for lambda with parameters with formal types. """
        parse.parse(self._class_template("(int foo) -> { return foo + 2; };"))
        parse.parse(self._class_template("(String s) -> s.length();"))
        parse.parse(self._class_template("(int foo) -> foo + 1;"))
        parse.parse(self._class_template("(Thread th) -> { th.start(); };"))
        parse.parse(self._class_template("(String foo, String bar) -> "
                                         "foo + bar;"))

    @unittest.expectedFailure
    def test_parameters_with_no_type_expression_body(self):
        """ currently there is no support for multiple lambda parameters
            that are specified without their types.
        """
        parse.parse(self._class_template("(x, y) -> x+y;"))

    def test_parameters_with_mixed_inferred_and_declared_types(self):
        """ this tests that lambda type specification mixing is considered
            invalid as per the specifications.
        """
        with self.assertRaises(parser.JavaSyntaxError):
            parse.parse(self._class_template("(x, int y) -> x+y;"))

    def test_parameters_inferred_types_with_modifiers(self):
        """ this tests that lambda inferred type parameters with modifiers are
            considered invalid as per the specifications.
        """
        with self.assertRaises(parser.JavaSyntaxError):
            parse.parse(self._class_template("(x, final y) -> x+y;"))


def main():
    unittest.main()

if __name__ == '__main__':
    main()

@@ -3446,16 +3446,1178 @@
 y;%22))%0A%0A%0A
+class MethodReferenceSyntaxTest(unittest.TestCase):%0A    %22%22%22 Contains tests for java 8 method reference syntax. %22%22%22%0A%0A    def _class_template(self, content_to_add):%0A        %22%22%22 returns an example java class with the%0A            given content_to_add contained within a method.%0A        %22%22%22%0A        template = %22%22%22%0Apublic class Lambda %7B%0A%0A    public static void main(String args%5B%5D) %7B%0A        %25s%0A    %7D%0A%7D%0A        %22%22%22%0A        return template %25 content_to_add%0A%0A    def test_method_reference(self):%0A        %22%22%22 tests that method references are supported. %22%22%22%0A        parse.parse(self._class_template(%22String::length;%22))%0A%0A    @unittest.expectedFailure%0A    def test_method_reference_explicit_type_arguments_for_generic_type(self):%0A        %22%22%22 currently there is no support for method references%0A            to an explicit type.%0A        %22%22%22%0A        parse.parse(self._class_template(%22List%3CString%3E::size;%22))%0A%0A    @unittest.expectedFailure%0A    def test_method_reference_explicit_type_arguments(self):%0A        %22%22%22 currently there is no support for method references%0A            to an explicit type.%0A        %22%22%22%0A        parse.parse(self._class_template(%22Arrays::%3CString%3E sort;%22))%0A%0A%0A
 def main

Add tests for java 8 method references.