Ejemplo n.º 1
0
    def test_js_manager(self):
        # Not existing component
        self.assertRaises(
            ValueError,
            Bigpipe.get().processors.run_processor,
            Bigpipe.get().config.processors.jsx.processor_name,
            "dasdasdasd",
        )

        # Existing working component
        processor_result = Bigpipe.get().processors.run_processor(
            Bigpipe.get().config.processors.jsx.processor_name, "TestMainPage")
        fp = open(processor_result.output_file, "r")
        content = fp.read()
        fp.close()

        self.assertNotEqual(content, None)
        self.assertNotEqual(content, "")
        self.assertNotEqual(content.index("i am the second page"), -1)
        self.assertNotEqual(content.index("HERE I AM"), -1)

        # Component with error
        with self.assertRaises(ValueError):
            Bigpipe.get().processors.run_processor(
                Bigpipe.get().config.processors.jsx.processor_name,
                "ComponentWithError")

        try:
            Bigpipe.get().processors.run_processor(
                Bigpipe.get().config.processors.jsx.processor_name,
                "ComponentWithError")
        except Exception as e:
            self.assertGreater(
                str(e).index("Expected corresponding JSX closing tag"), 0)
Ejemplo n.º 2
0
    def __init__(self,
                 render_type: str,
                 render_source: str = None,
                 render_context: str = {},
                 render_options: BigpipeRenderOptions = None,
                 js_dependencies: list = [],
                 scss_dependencies: list = [],
                 i18n_dependencies: list = []):
        if render_type is None:
            raise ValueError('render_type cannot be None')
        if render_source is None:
            raise ValueError('render_source cannot be None')
        if render_context is None or not isinstance(render_context, dict):
            raise ValueError('render context must be a dict')
        if render_options is not None and not isinstance(
                render_options, BigpipeRenderOptions):
            raise ValueError(
                'render_options can be None or instance of BigpipeRenderOptions'
            )
        render_source_unmarshalled = DependenciesMarshalling.unmarshall(
            render_source)[0]
        if render_source_unmarshalled['link']:
            raise ValueError('render_source cannot be link')

        self.render_options = Bigpipe.get().get_render_option(render_options)
        self.render_type = render_type
        self.render_source = render_source_unmarshalled['source']
        self.render_source_processor_name = render_source_unmarshalled[
            'processor_name'] or self.render_options.js_processor_name
        self.render_context = render_context
        self.js_dependencies = js_dependencies
        self.scss_dependencies = scss_dependencies
        self.i18n_dependencies = i18n_dependencies

        self.local_language = translation.get_language()
 def test_multiple_processors(self):
     module_processor_name = Bigpipe.get(
     ).config.processors.js_modules.processor_name
     content_loader = ContentLoader(
         render_type=BigpipeResponse.RenderType.JAVASCRIPT,
         render_source='TestMainPage',
         js_dependencies=['simple_js_file'] +
         to_include([
             'React=react', 'ReactDOM=react-dom',
             'createReactClass=create-react-class'
         ],
                    is_link=False,
                    processor_name=module_processor_name),
         scss_dependencies=['main'],
         i18n_dependencies=["CONST_USER_open_question_placeholder.*"])
     content_result = content_loader.load_content('body', [], [])
     self.assertNotEqual(content_result.content, None)
     self.assertNotEqual(content_result.js, None)
     self.assertNotEqual(content_result.css, None)
     self.assertNotEqual(content_result.i18n, None)
     self.assertGreater(
         content_result.js.index(
             "Copyright (c) Facebook, Inc. and its affiliates"), 1)
     self.assertGreater(content_result.js.index("react.production.min.js"),
                        1)
     self.assertGreater(
         content_result.js.index("react-dom.production.min.js"), 1)
Ejemplo n.º 4
0
    def test_css_manager(self):
        processor_result = Bigpipe.get().processors.run_processor(
            Bigpipe.get().config.processors.css.processor_name, "main")
        fp = open(processor_result.output_file, "r")
        content = fp.read()
        fp.close()

        self.assertNotEqual(content, None)
        self.assertNotEqual(content, "")

        self.assertRaises(
            ValueError,
            Bigpipe.get().processors.run_processor,
            Bigpipe.get().config.processors.css.processor_name,
            "paramsadasd",
        )
Ejemplo n.º 5
0
    def __get_dependencies_links(self, processors_name_order: list,
                                 processor_name_to_sources: list,
                                 bundle_dependencies: bool):
        links, output_files = [], []
        render_options = {'output_file_prefix': '@'}
        for processor_name in processors_name_order:
            # Validating that 'processor_name' exists in the include list.
            # since 'processors_name_ordered' is a list of all processors names (links and content).
            # it may be that the processor_name dose not have links to process
            if processor_name in processor_name_to_sources:
                sources = processor_name_to_sources[processor_name]
                if bundle_dependencies:
                    source_name = self.render_source if self.render_source else sources[
                        0]
                    output_files = output_files + [
                        self.__run_processor(
                            processor_name,
                            source_name,
                            sources,
                            options=render_options,
                            generate_missing_source=True).output_file
                    ]
                else:
                    output_files = output_files + [
                        self.__run_processor(
                            processor_name,
                            source_name,
                            options=render_options,
                            generate_missing_source=False).output_file
                        for source_name in sources
                    ]

        static_uri = Bigpipe.get().config.static_uri.strip(
            '/') if Bigpipe.get().config.static_uri else ''

        # Build the path for the browser
        for output_file in output_files:
            output_directory_length = len(
                Bigpipe.get().config.rendered_output_path)
            output_file = output_file[output_directory_length::].replace(
                '\\', '/')
            links.append('{}/{}'.format(static_uri, output_file.strip('/')))
        return links
Ejemplo n.º 6
0
 def __run_processor(self,
                     bigpipe_processor_name: str,
                     source: str,
                     include_dependencies: list = [],
                     exclude_dependencies: list = [],
                     options: dict = {},
                     generate_missing_source: bool = False):
     render_source = source.replace('.', '_')
     return Bigpipe.get().processors.run_processor(
         bigpipe_processor_name,
         render_source,
         options,
         include_dependencies,
         exclude_dependencies,
         generate_missing_source=generate_missing_source)
    def test_links_in_results(self):
        content_loader = ContentLoader(
            render_type=BigpipeResponse.RenderType.JAVASCRIPT,
            render_source='TestMainPage',
            js_dependencies=['@simple_js_file'],
            scss_dependencies=['@main'])

        content_result = content_loader.load_content('body', [], [])
        self.assertNotEqual(content_result.js_links, None)
        self.assertEqual(len(content_result.js_links), 1)
        for js_link in content_result.js_links:
            link_path = os.path.normpath('{}/{}'.format(
                Bigpipe.get().config.rendered_output_path, js_link))
            self.assertEqual(os.path.isfile(link_path), True)
            file_content = open(link_path, mode='r', encoding='utf-8').read()
            self.assertGreaterEqual(
                file_content.index("function_inside_simple_js_object"), 0)

        for css_link in content_result.css_links:
            link_path = os.path.normpath('{}/{}'.format(
                Bigpipe.get().config.rendered_output_path, css_link))
            self.assertEqual(os.path.isfile(link_path), True)
            file_content = open(link_path, mode='r', encoding='utf-8').read()
            self.assertGreaterEqual(file_content.index(".test-class"), 0)
Ejemplo n.º 8
0
 def to_dict(self, paglet_target: str):
     result = {'target': paglet_target}
     if self.css:
         result['css'] = self.css
     if self.content:
         result['html'] = self.content
     if self.js:
         result['js'] = self.js
     if self.i18n:
         result['i18n'] = self.i18n
     if self.js_links:
         result['js_links'] = self.js_links
     if self.css_links:
         result['css_links'] = self.css_links
     if Bigpipe.get().config.is_production_mode:
         result['remove'] = True
     return result
Ejemplo n.º 9
0
 def tearDown(self):
     print("shutdown Bigpipe")
     Bigpipe.get().shutdown()
Ejemplo n.º 10
0
def handle_kill(signum, frame):
    print('Signal terminate received will shutdown bigpipe')
    from bigpipe_response.bigpipe import Bigpipe
    Bigpipe.get().shutdown()
    sys.exit(0)
Ejemplo n.º 11
0
 def tearDown(self):
     print('Shutdown Bigpipe')
     Bigpipe.get().shutdown()
from bigpipe_response.helpers import to_include

from bigpipe_response.bigpipe_response import BigpipeResponse
from bigpipe_response.pagelet import Pagelet

from bigpipe_response_example.bigpipe_processors.VueDOMBind import VueDOMBind
from data.app_instance import AppInstance

demo_dao = AppInstance.get()

js_dependencies = to_include([
    'React=react', 'ReactDOM=react-dom', 'createReactClass=create-react-class',
    'Vue=vue.default'
],
                             is_link=True,
                             processor_name=Bigpipe.get().config.processors.
                             js_modules.params.processor_name)


def demo(request):

    pagelets = [
        Pagelet(request, 'vue-container', vue_view, {}),
        Pagelet(request, 'markdown-container', markdown_view, {}),
    ]
    return BigpipeResponse(request,
                           render_type=BigpipeResponse.RenderType.TEMPLATE,
                           render_source='demoMultipleFrameworks.html',
                           pagelets=pagelets,
                           js_dependencies=js_dependencies,
                           scss_dependencies=['@demo_main'])
Ejemplo n.º 13
0
    def process_resource(self,
                         input_file: str,
                         output_file: str,
                         include_dependencies: list,
                         exclude_dependencies: list,
                         options: dict = {}):
        effected_files = []

        def importer_returning_one_argument(path, prev):
            effected_file = os.path.splitext(os.path.basename(path))[0]
            effected_files.append(effected_file)
            if effected_file in exclude_dependencies:
                return []
            return [(path, )]

        # DEVELOPMENT MODE mode files may change
        # Re-crate the include path
        if not self.is_production_mode:
            self.include_paths = self.__generate_include_paths()

        # Include the main file
        import_full_paths = []
        if not self.is_component_virtual(
                os.path.splitext(os.path.basename(input_file))[0]):
            import_full_paths.append(input_file)

        import_paths = []
        for dependency in include_dependencies:
            if dependency in self._component_to_file:
                component_file = self._component_to_file[dependency]
                import_full_paths.append(component_file)
                import_paths.append(os.path.dirname(component_file))
            else:
                logger.warning(
                    'dependency `{}` is  not registered'.format(dependency))

        source_list = []
        for full_path in list(set(import_full_paths)):
            source_list.append('@import \'{}\';'.format(
                full_path.replace('\\', '/')))  # replace case of windows

        from bigpipe_response.bigpipe import Bigpipe
        include_paths = import_paths + self.include_paths + [
            os.path.join(Bigpipe.get().javascript_folder, 'node_modules')
        ]

        include_paths.sort()
        source_list.sort()
        if source_list or include_paths:
            compiled = sass.compile(string=''.join(source_list),
                                    include_paths=include_paths,
                                    importers=((
                                        0,
                                        importer_returning_one_argument,
                                    ), ),
                                    output_style='compressed'
                                    if self.is_production_mode else 'expanded')

            fp = open(output_file, "w", encoding='utf-8')
            fp.write(compiled)
            fp.close()
        else:
            logger.warning('nothing to compile')

        return effected_files
Ejemplo n.º 14
0
 def __render_processor(self, bigpipe_processor_name: str, source: str,
                        context: dict, i18n: dict):
     return Bigpipe.get().processors.render_processor(
         bigpipe_processor_name, source, context, i18n)
Ejemplo n.º 15
0
import os
import unittest

from bigpipe_response.bigpipe import Bigpipe
from tests.test_utils import TestUtils

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tests.settings')

TestUtils.setup_logger()
config = TestUtils.get_test_configuration()
Bigpipe.init(config.bigpipe_response)
print("Installing javascript dependencies.")

TestUtils.empty_output_folder(Bigpipe.get().config.rendered_output_path)


class TestBigpipeProcessor(unittest.TestCase):
    def tearDown(self):
        print("shutdown Bigpipe")
        Bigpipe.get().shutdown()

    def test_css_manager(self):
        processor_result = Bigpipe.get().processors.run_processor(
            Bigpipe.get().config.processors.css.processor_name, "main")
        fp = open(processor_result.output_file, "r")
        content = fp.read()
        fp.close()

        self.assertNotEqual(content, None)
        self.assertNotEqual(content, "")
Ejemplo n.º 16
0
 def __filter_unregistered_dependencies(self, processor_name,
                                        css_extra_files):
     return Bigpipe.get().processors.filter_unregistered_dependencies(
         processor_name, css_extra_files)
Ejemplo n.º 17
0
    def __stream_content(self):
        last_pagelet_target = None
        try:
            content_result = self.content_loader.load_content('body', [], [])
            self.processed_js_files = self.processed_js_files + content_result.js_effected_files
            self.processed_css_files = self.processed_css_files + content_result.css_effected_files

            for entry_content in self.__build_bigpipe_data_main_yield(content_result):
                yield entry_content

            dependencies = {}
            que = queue.Queue()
            paglent_count = len(self.pagelets)
            for pagelet in self.pagelets:
                last_pagelet_target = pagelet.target
                if pagelet.depends_on:
                    dependencies[pagelet.target] = pagelet.depends_on
                threading.Thread(target=self.__process_paglet, args=(pagelet, que), daemon=True).start()

            # Validate dependencies
            self.__validate_deendencies(dependencies)

            yield_paglets = []
            yield_later = {}
            for _ in range(paglent_count):
                content_result_pagelet = que.get()

                if not isinstance(content_result_pagelet, ContentResult):
                    content_result_pagelet_type = type(content_result_pagelet) if content_result_pagelet else None
                    self.logger.error('expected `ContentResult` got `{}` return for pagelet path `{}`'.format(content_result_pagelet_type, self.request.path))
                    if isinstance(content_result_pagelet, HttpResponseBase):
                        raise ValueError(f'pagelet with url `{content_result_pagelet.url}` Expected `ContentResult`, got `HttpResponseBase` instead')
                    raise content_result_pagelet

                bigpipe_paglet_data = content_result_pagelet.to_dict(pagelet.target)
                # Handle depends_on
                # When depends_on flag is set, the result will be cached and pushed only after the dependency is loaded
                target = bigpipe_paglet_data['target']
                if target in dependencies:
                    dependent_target = dependencies.get(target)
                    if dependent_target not in yield_paglets:
                        yield_later.setdefault(dependent_target, []).append(bigpipe_paglet_data)
                        continue

                yield_paglets.append(target)
                yield self._render_paglet_content(bigpipe_paglet_data)

                if target in yield_later:
                    for yield_pagelet_response in yield_later.get(target):
                        yield self._render_paglet_content(yield_pagelet_response)
                    del yield_later[target]

            for target, yield_pagelet_response in yield_later.items():
                yield self._render_paglet_content(yield_pagelet_response)
                del yield_later[target]

        except BaseException as ex:
            self.logger.error("Error handling bigpipe response", exc_info=sys.exc_info())

            if not Bigpipe.get().config.is_production_mode: # DEVELOPMENT MODE
                error_target = 'Error in request source [{}]{}'.format(self.content_loader.render_source, ', on pagelet target element [{}]'.format(last_pagelet_target) if last_pagelet_target else '')
                content, js, css = BigpipeDebugger.get_exception_content(error_target, (str(ex.errors) if hasattr(ex, 'errors') else str(ex)), traceback.format_exc())
                i18n = {}
                content_result_error = ContentResult(content, js, css, i18n, [], [], [], [])
                if last_pagelet_target:
                    yield self._render_paglet_content(content_result_error.to_dict(last_pagelet_target))
                else:
                    for entry_content in self.__build_bigpipe_data_main_yield(content_result_error):
                        yield entry_content
            else:
                raise ex

        yield '</body></html>\n'