Beispiel #1
0
 def test_bad_callback_objects_raise_exception(self):
     inst = Sijax()
     try:
         inst.execute_callback(callback='non-callable object', args=[])
         self.fail('SijaxError not raised when bad callback was given!')
     except SijaxError:
         pass
Beispiel #2
0
 def test_bad_callback_objects_raise_exception(self):
     inst = Sijax()
     try:
         inst.execute_callback(callback='non-callable object', args=[])
         self.fail('SijaxError not raised when bad callback was given!')
     except SijaxError:
         pass
Beispiel #3
0
    def test_regular_functions_that_yield_are_not_allowed(self):
        # Yielding is only supported by streaming functions.
        # It makes no sense for regular functions to use it.
        # If a regular function tries to yield, we expect
        # a SijaxError to be raised

        inst = Sijax()
        def callback(obj_response):
            yield obj_response

        try:
            inst.execute_callback([], callback)
            self.fail("Yielding regular function didn't raise expected exception!")
        except SijaxError:
            pass
Beispiel #4
0
    def test_regular_functions_that_yield_are_not_allowed(self):
        # Yielding is only supported by streaming functions.
        # It makes no sense for regular functions to use it.
        # If a regular function tries to yield, we expect
        # a SijaxError to be raised

        inst = Sijax()

        def callback(obj_response):
            yield obj_response

        try:
            inst.execute_callback([], callback)
            self.fail(
                "Yielding regular function didn't raise expected exception!")
        except SijaxError:
            pass
    def test_executing_regular_callbacks_works(self):
        from types import StringType

        calls_history = []
        call_args_history = []

        def event_before(obj_response):
            self.assertTrue(isinstance(obj_response, BaseResponse))
            calls_history.append("before")

            obj_response.script("javascript here..")

        def event_after(obj_response):
            self.assertTrue(isinstance(obj_response, BaseResponse))
            calls_history.append("after")

            obj_response.css("#element", "backgroundColor", "red")

        def callback_main(obj_response, arg1, arg2):
            self.assertTrue(isinstance(obj_response, BaseResponse))

            calls_history.append("main")
            call_args_history.append(arg1)
            call_args_history.append(arg2)

            obj_response.alert("alert from main")

        inst = Sijax()
        cls = inst.__class__
        inst.register_event(cls.EVENT_BEFORE_PROCESSING, event_before)
        inst.register_event(cls.EVENT_AFTER_PROCESSING, event_after)

        call_args = ["arg1", 15]
        response = inst.execute_callback(call_args, callback=callback_main)

        self.assertEqual(["before", "main", "after"], calls_history)
        self.assertEqual(call_args, call_args_history)

        # the response should be a string for regular functions
        # streaming functions return generators instead..
        self.assertTrue(isinstance(response, StringType))

        from sijax.helper import json
        try:
            commands = json.loads(response)
        except:
            self.fail("Invalid JSON response!")
        else:
            self.assertTrue(isinstance(commands, list))

            commands_history = []
            for cmd_params in commands:
                self.assertTrue(isinstance(cmd_params, dict))
                self.assertTrue("type" in cmd_params, "Unknown command type!")
                commands_history.append(cmd_params["type"])

        self.assertEqual(["script", "alert", "css"], commands_history)
Beispiel #6
0
    def test_executing_regular_callbacks_works(self):

        calls_history = []
        call_args_history = []

        def event_before(obj_response):
            self.assertTrue(isinstance(obj_response, BaseResponse))
            calls_history.append("before")

            obj_response.script("javascript here..")

        def event_after(obj_response):
            self.assertTrue(isinstance(obj_response, BaseResponse))
            calls_history.append("after")

            obj_response.css("#element", "backgroundColor", "red")

        def callback_main(obj_response, arg1, arg2):
            self.assertTrue(isinstance(obj_response, BaseResponse))

            calls_history.append("main")
            call_args_history.append(arg1)
            call_args_history.append(arg2)

            obj_response.alert("alert from main")

        inst = Sijax()
        cls = inst.__class__
        inst.register_event(cls.EVENT_BEFORE_PROCESSING, event_before)
        inst.register_event(cls.EVENT_AFTER_PROCESSING, event_after)

        call_args = ["arg1", 15]
        response = inst.execute_callback(call_args, callback=callback_main)

        self.assertEqual(["before", "main", "after"], calls_history)
        self.assertEqual(call_args, call_args_history)

        # the response should be a string for regular functions
        # streaming functions return generators instead..
        self.assertTrue(isinstance(response, string_types))

        from sijax.helper import json
        try:
            commands = json.loads(response)
        except:
            self.fail("Invalid JSON response!")
        else:
            self.assertTrue(isinstance(commands, list))

            commands_history = []
            for cmd_params in commands:
                self.assertTrue(isinstance(cmd_params, dict))
                self.assertTrue("type" in cmd_params, "Unknown command type!")
                commands_history.append(cmd_params["type"])

        self.assertEqual(["script", "alert", "css"], commands_history)
Beispiel #7
0
    def test_streaming_functions_return_generators(self):
        # Every function registered as streaming should return a generator
        # when it's executed, even if the actual function decides to act
        # as a normal function, and not generate anything
        # This is very important, because it allows mixing streaming with
        # regular functions when the StreamingIframeResponse is used

        from types import GeneratorType

        call_history = []

        def callback_before(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("before")
            obj_response.html("#div", "before html")

        def callback_after(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("after")
            # intentionally not pushing new commands
            # which means it should not be yielding at implicitly

        def callback_yielding(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("yielding")
            obj_response.alert("test")
            yield obj_response
            obj_response.css("#div", "color", "red")

        def callback_normal(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("normal")
            obj_response.script(".. javascript here..")

        def assert_generator_entries_length(generator, length):
            items = []
            try:
                while True:
                    items.append(next(generator))
            except StopIteration:
                pass

            self.assertEqual(length, len(items))

        inst = Sijax()
        cls = inst.__class__
        inst.register_event(cls.EVENT_BEFORE_PROCESSING, callback_before)
        inst.register_event(cls.EVENT_AFTER_PROCESSING, callback_after)
        options = {cls.PARAM_RESPONSE_CLASS: StreamingIframeResponse}

        response = inst.execute_callback([],
                                         callback=callback_yielding,
                                         **options)
        self.assertTrue(isinstance(response, GeneratorType))
        # We should have the following yields:
        # 1. Implicit yield after callback_before
        # 2. Explicit yield from callback_yielding
        # 3. Implicit yield when calback_yielding ends
        # Note that callback_after should not yield implicitly,
        # because it has not pushed new commands, so it makes no sense!
        assert_generator_entries_length(response, 3)

        def callback_before_new(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("before_new")

            # this doesn't really push data, as we haven't added commands yet
            # flushing would be wasteful
            for i in range(10):
                yield obj_response

            for i in range(2):
                obj_response.alert("hey")
                yield obj_response

        inst.register_event(cls.EVENT_BEFORE_PROCESSING, callback_before_new)
        inst.register_event(cls.EVENT_AFTER_PROCESSING,
                            lambda r: r.alert("this yields"))
        response = inst.execute_callback([],
                                         callback=callback_normal,
                                         **options)
        self.assertTrue(isinstance(response, GeneratorType))
        # We're expecting the following yields:
        # 1. Explicit yield from callback_before_new
        # 2. Explicit yield from callback_before_new
        # 3. Implicit yield after callback_normal
        # 4. Implicit yield after EVENT_AFTER_PROCESSING callback
        assert_generator_entries_length(response, 4)

        call_history_expected = [
            "before", "yielding", "after", "before_new", "normal"
        ]
        self.assertEqual(call_history_expected, call_history)
Beispiel #8
0
    def test_streaming_functions_return_generators(self):
        # Every function registered as streaming should return a generator
        # when it's executed, even if the actual function decides to act
        # as a normal function, and not generate anything
        # This is very important, because it allows mixing streaming with
        # regular functions when the StreamingIframeResponse is used

        from types import GeneratorType

        call_history = []

        def callback_before(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("before")
            obj_response.html("#div", "before html")

        def callback_after(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("after")
            # intentionally not pushing new commands
            # which means it should not be yielding at implicitly

        def callback_yielding(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("yielding")
            obj_response.alert("test")
            yield obj_response
            obj_response.css("#div", "color", "red")

        def callback_normal(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("normal")
            obj_response.script(".. javascript here..")

        def assert_generator_entries_length(generator, length):
            items = []
            try:
                while True:
                    items.append(next(generator))
            except StopIteration:
                pass

            self.assertEqual(length, len(items))

        inst = Sijax()
        cls = inst.__class__
        inst.register_event(cls.EVENT_BEFORE_PROCESSING, callback_before)
        inst.register_event(cls.EVENT_AFTER_PROCESSING, callback_after)
        options = {cls.PARAM_RESPONSE_CLASS: StreamingIframeResponse}

        response = inst.execute_callback([], callback=callback_yielding, **options)
        self.assertTrue(isinstance(response, GeneratorType))
        # We should have the following yields:
        # 1. Implicit yield after callback_before
        # 2. Explicit yield from callback_yielding
        # 3. Implicit yield when calback_yielding ends
        # Note that callback_after should not yield implicitly,
        # because it has not pushed new commands, so it makes no sense!
        assert_generator_entries_length(response, 3)

        def callback_before_new(obj_response):
            self.assertTrue(isinstance(obj_response, StreamingIframeResponse))
            call_history.append("before_new")

            # this doesn't really push data, as we haven't added commands yet
            # flushing would be wasteful
            for i in range(10):
                yield obj_response

            for i in range(2):
                obj_response.alert("hey")
                yield obj_response

        inst.register_event(cls.EVENT_BEFORE_PROCESSING, callback_before_new)
        inst.register_event(cls.EVENT_AFTER_PROCESSING, lambda r: r.alert("this yields"))
        response = inst.execute_callback([], callback=callback_normal, **options)
        self.assertTrue(isinstance(response, GeneratorType))
        # We're expecting the following yields:
        # 1. Explicit yield from callback_before_new
        # 2. Explicit yield from callback_before_new
        # 3. Implicit yield after callback_normal
        # 4. Implicit yield after EVENT_AFTER_PROCESSING callback
        assert_generator_entries_length(response, 4)

        call_history_expected = [
            "before", "yielding", "after",
            "before_new", "normal"
        ]
        self.assertEqual(call_history_expected, call_history)