Exemplo n.º 1
0
    def test_print_css_stats(self):
        # On Travis CI these auto-generated files are inaccessible and need to be recreated.
        # Change the expected file size reduction percentage since Ubuntu's math is different.
        # Create directories and CSS files if they do not exist.
        blowdry_css = unittest_file_path('test_examplesite/test_css', 'blowdry.css')
        blowdry_min_css = unittest_file_path('test_examplesite/test_css', 'blowdry.min.css')

        #if not path.isfile(blowdry_css) or not path.isfile(blowdry_min_css):
        substrings = [
            'blowdry.css:\t 0.3kB',
            'blowdry.min.css: 0.2kB',
            'CSS file size reduced by 28.4%.'
        ]

        blowdry_css_text = '.bgc-hf8f8f8 {\n    background-color: #f8f8f8\n    }\n.border-1px-solid-gray {\n    border: 1px solid gray\n    }\n.padding-5 {\n    padding: 0.3125em\n    }\n.bold {\n    font-weight: bold\n    }\n.talign-center {\n    text-align: center\n    }\n.display-inline {\n    display: inline\n    }'
        blowdry_min_css_text = '.bgc-hf8f8f8{background-color:#f8f8f8}.border-1px-solid-gray{border:1px solid gray}.padding-5{padding:.3125em}.bold{font-weight:bold}.talign-center{text-align:center}.display-inline{display:inline}'

        # Create directories.
        make_directory(unittest_file_path('test_examplesite', ''))
        make_directory(unittest_file_path('test_examplesite/test_css', ''))

        # Create files.
        with open(blowdry_css, 'wb') as generic_file:
            generic_file.write(bytearray(blowdry_css_text, 'utf-8'))

        with open(blowdry_min_css, 'wb') as generic_file:
            generic_file.write(bytearray(blowdry_min_css_text, 'utf-8'))

        # Handle printed output.
        saved_stdout = sys.stdout
        try:
            out = StringIO()
            sys.stdout = out

            print_css_stats(file_name='blowdry')

            output = out.getvalue()
            for substring in substrings:
                self.assertTrue(substring in output, msg=substring + '\noutput:\n' + output)
        finally:
            sys.stdout = saved_stdout
Exemplo n.º 2
0
    def test_print_css_stats_ZeroDivisionError(self):
        # On Travis CI these auto-generated files are inaccessible and need to be recreated.
        # Change the expected file size reduction percentage since Ubuntu's math is different.
        # Create directories and CSS files if they do not exist.
        empty_css = unittest_file_path('test_examplesite/test_css', 'empty.css')
        empty_min_css = unittest_file_path('test_examplesite/test_css', 'empty.min.css')

        #if not path.isfile(blowdry_css) or not path.isfile(blowdry_min_css):
        substrings = [
            'empty.css:\t 0.0kB',
            'empty.min.css: 0.0kB',
            'CSS file size reduced by 0.0%.'
        ]

        # Create directories.
        make_directory(unittest_file_path('test_examplesite', ''))
        make_directory(unittest_file_path('test_examplesite/test_css', ''))

        # Create files.
        with open(empty_css, 'w') as generic_file:
            generic_file.write(u'')

        with open(empty_min_css, 'w') as generic_file:
            generic_file.write(u'')

        # Handle printed output.
        saved_stdout = sys.stdout
        try:
            out = StringIO()
            sys.stdout = out

            print_css_stats(file_name='empty')

            output = out.getvalue()
            for substring in substrings:
                self.assertTrue(substring in output, msg=substring + '\noutput:\n' + output)
        finally:
            sys.stdout = saved_stdout
            delete_file_paths((empty_css, empty_min_css, ))
Exemplo n.º 3
0
def parse(recent=True, class_set=set(), css_text=b''):
    """ It parses every eligible file in the project i.e. file type matches an element of settings.file_types.
    This ensures that from time to time unused CSS class selectors are removed from blowdry.css.

    **Order of Operations:**

    - Initialize settings.
    - Start performance timer.
    - Define File all file types/extensions to search for in project_directory
    - Get all files associated with defined file_types in project_directory
    - Get set of all defined classes
    - Filter class names only keeping classes that match the defined class encoding.
    - Build a set() of valid css properties. Some classes may be removed during cssutils validation.
    - Output the DRY CSS file. (user command option)
    - Output the Minified DRY CSS file. (user command option)

    **Depending on the settings this script generates the following:**

    - DRY CSS files
        - blowdry.css |sp| |sp| |sp| |sp| |sp| **human readable**
        - blowdry.min.css |sp| **minified**

    - Clashing Alias files (Encoded class selector aliases that are invalid and cannot be used because they clash.)
        - Markdown |sp| |sp| |sp| |sp| |sp| |sp| **Github**
        - HTML |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| **Browser**
        - reStructuredText |sp| **Sphinx**

    - Property Alias File (Encoded class selector aliases that are valid and can be used to construct class selectors.)
        - Markdown |sp| |sp| |sp| |sp| |sp| |sp| **Github**
        - HTML |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| **Browser**
        - reStructuredText |sp| **Sphinx**

    - Temporal Statistics

    **Note:** The default locations of these files can be overridden to suit your needs.

    **Directory assignments**
    ``project_directory`` -- Allows ``blowdrycss`` to know where the HTML project is located. It will only search
    the files in the directory specified here.

.. |sp| raw:: html

     

    :param css_text:
    :type recent: bool
    :param recent: Flag that indicates whether to parse the most recently modified files (True Case)
      or all eligible files (False Case).

    :type class_set: set
    :param class_set: The set of known css class selectors.

    :type css_text: bytes
    :param css_text: The current version of the CSS text.

    """
    if settings.timing_enabled:
        from blowdrycss.timing import Timer
        timer = Timer()

    print('\n~~~ blowdrycss started ~~~')

    # Get files to parse.
    file_finder = FileFinder(recent=recent)

    # Create set of all defined classes
    class_parser = ClassParser(file_dict=file_finder.file_dict)

    # Unite class sets during on_modified case.
    if recent:
        modified_class_set = class_parser.class_set
        use_this_set = modified_class_set.difference(class_set)
    else:
        use_this_set = class_parser.class_set

    # Filter class names. Only keep classes matching the defined class encoding.
    class_property_parser = ClassPropertyParser(class_set=use_this_set)
    logging.info(msg='blowdry.class_property_parser.class_set:\t' + str(class_property_parser.class_set))
    use_this_set = class_property_parser.class_set.copy()

    # Build a set() of valid css properties. Some classes may be removed during cssutils validation.
    css_builder = CSSBuilder(property_parser=class_property_parser)
    css_text += bytes(css_builder.get_css_text())
    builder_class_set = css_builder.property_parser.class_set.copy()

    # Build Media Queries
    if settings.media_queries_enabled:
        unassigned_class_set = use_this_set.difference(css_builder.property_parser.class_set)
        css_builder.property_parser.class_set = unassigned_class_set.copy()             # Only use unassigned classes
        css_builder.property_parser.removed_class_set = set()                           # Clear set
        media_query_builder = MediaQueryBuilder(property_parser=class_property_parser)
        logging.debug(
            msg=(
                'blowdry.media_query_builder.property_parser.class_set:\t' +
                str(media_query_builder.property_parser.class_set)
            )
        )
        css_text += bytes(media_query_builder.get_css_text(), 'utf-8')

        media_class_set = unassigned_class_set.intersection(media_query_builder.property_parser.class_set)

        if recent:
            class_set = class_set.union(builder_class_set)
            class_set = class_set.union(media_class_set)
        else:
            class_set = builder_class_set.copy()
            class_set = class_set.union(media_class_set)
    else:
        if recent:
            class_set = class_set.union(builder_class_set)
        else:
            class_set = builder_class_set.copy()

    logging.debug('\nCSS Text:\n\n' + str(css_text))
    print('\nAuto-Generated CSS:')

    # Output the DRY CSS file. (user setting option)
    if settings.human_readable:
        css_file = CSSFile(file_directory=settings.css_directory, file_name='blowdry')
        css_file.write(css_text=css_text)
        print(path.join(settings.css_directory, css_file.file_name) + '.css')

    # Output the Minified DRY CSS file. (user setting option)
    if settings.minify:
        css_file = CSSFile(file_directory=settings.css_directory, file_name='blowdry')
        css_file.minify(css_text=css_text)
        print(path.join(settings.css_directory, css_file.file_name) + '.min.css')

    if settings.timing_enabled:
        timer.report()

    if settings.minify:
        print_css_stats(file_name='blowdry')

    return class_set, css_text