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)
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)
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", )
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
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)
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
def tearDown(self): print("shutdown Bigpipe") Bigpipe.get().shutdown()
def handle_kill(signum, frame): print('Signal terminate received will shutdown bigpipe') from bigpipe_response.bigpipe import Bigpipe Bigpipe.get().shutdown() sys.exit(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'])
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
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)
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, "")
def __filter_unregistered_dependencies(self, processor_name, css_extra_files): return Bigpipe.get().processors.filter_unregistered_dependencies( processor_name, css_extra_files)
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'