def test_set_custom_breakpoint_key_Valid(self):
        valid_css_classes = (
            'padding-25-820-up', 'display-480-down', 'margin-5-2-5-2-1000-up', 'display-960-up-i', 'display-3_2rem-down'
        )
        names = ['padding', 'display', 'margin', 'display', 'display', ]
        values = ['25', 'none', '5-2-5-2', 'none', 'none', ]
        priorities = ['', '', '', 'important', '', ]
        limit_key = ('-up', '-down', '-up', '-up', '-down', )
        breakpoint = ('-820', '-480', '-1000', '-960', '-3_2rem', )
        converted_breakpoint = (px_to_em('820'), px_to_em('480'), px_to_em('1000'), px_to_em('960'), '3.2rem', )

        for i, css_class in enumerate(valid_css_classes):
            css_property = Property(name=names[i], value=values[i], priority=priorities[i])
            breakpoint_parser = BreakpointParser(css_class=css_class, css_property=css_property)
            self.assertTrue(breakpoint_parser.is_breakpoint, msg=breakpoint_parser.css_class)
            self.assertEqual(
                breakpoint_parser.breakpoint_dict['custom'][limit_key[i]],
                converted_breakpoint[i],
                msg=converted_breakpoint[i] + ' dict: ' + breakpoint_parser.breakpoint_dict['custom'][limit_key[i]]
            )
            self.assertEqual(
                breakpoint_parser.breakpoint_dict['custom']['breakpoint'],
                breakpoint[i],
                msg=breakpoint[i] + ' dict: ' + breakpoint_parser.breakpoint_dict['custom']['breakpoint']
            )
 def test_build_media_query_invalid_limit_key(self):
     css_class = 'padding-100-small-up'
     name = 'padding'
     value = px_to_em('100')
     expected = ''
     css_property = Property(name=name, value=value, priority='')
     breakpoint_parser = BreakpointParser(css_class=css_class, css_property=css_property)
     breakpoint_parser.limit_key = 'invalid_key'
     css = breakpoint_parser.build_media_query()
     self.assertEqual(css, expected)
 def test_css_for_up_wrong_limit_key(self):
     css_class = 'padding-100-small-up'
     name = 'padding'
     value = px_to_em('100')
     expected = ''
     css_property = Property(name=name, value=value, priority='')
     breakpoint_parser = BreakpointParser(css_class=css_class, css_property=css_property)
     breakpoint_parser.limit_key = '-only'   # Change to WRONG LIMIT KEY
     css = breakpoint_parser.css_for_up()
     self.assertEqual(css, expected)
 def test_build_media_query_up_general_usage(self):
     css_class = 'padding-100-small-up'
     name = 'padding'
     value = px_to_em('100')
     expected = (
         '@media only screen and (min-width: 15.0625em) {\n' +
         '\t.padding-100-small-up {\n' +
         '\t\tpadding: 6.25em;\n' +
         '\t}\n' +
         '}\n\n'
     )
     css_property = Property(name=name, value=value, priority='')
     breakpoint_parser = BreakpointParser(css_class=css_class, css_property=css_property)
     css = breakpoint_parser.build_media_query()
     self.assertEqual(css, expected)
 def test_css_for_down_general_usage(self):
     css_class = 'padding-100-medium-down'
     name = 'padding'
     value = px_to_em('100')
     expected = (
         '@media only screen and (max-width: 45.0em) {\n' +
         '\t.padding-100-medium-down {\n' +
         '\t\tpadding: 6.25em;\n' +
         '\t}\n' +
         '}\n\n'
     )
     css_property = Property(name=name, value=value, priority='')
     breakpoint_parser = BreakpointParser(css_class=css_class, css_property=css_property)
     css = breakpoint_parser.css_for_down()
     self.assertEqual(css, expected)
 def test_css_for_only_general_usage_important(self):
     css_class = 'padding-100-large-only-i'
     name = 'padding'
     value = px_to_em('100')
     priority = 'important'
     expected = (
         '@media only screen and (min-width: 45.0625em) and (max-width: 64.0em) {\n' +
         '\t.padding-100-large-only-i {\n' +
         '\t\tpadding: 6.25em !important;\n' +
         '\t}\n' +
         '}\n\n'
     )
     css_property = Property(name=name, value=value, priority=priority)
     breakpoint_parser = BreakpointParser(css_class=css_class, css_property=css_property)
     css = breakpoint_parser.css_for_only()
     self.assertEqual(css, expected)
    def test_write_blowdrycss_settings_dot_py(self):
        settings_file = 'blowdrycss_settings.py'

        # Remove it if it exists.
        if path.isfile(settings_file):
            remove(settings_file)

        # Identical section of code from blowdrycss.py for test purposes.
        write_blowdrycss_settings_dot_py()

        # Import from the current folder.
        try:
            import blowdrycss_settings as settings                          # development case
        except ImportError:
            import blowdrycss.unit_tests.blowdrycss_settings as settings    # python setup.py test

        # test file existence
        self.assertTrue(path.isfile('blowdrycss_settings.py'))

        # test directory and file_type settings
        cwd = getcwd()
        self.assertTrue(
            settings.markdown_directory == path.join(cwd, 'docs', 'markdown'),
            msg=settings.markdown_directory + '\t' + path.join(cwd, 'docs', 'markdown')
        )
        self.assertTrue(settings.project_directory == cwd)
        self.assertTrue(settings.css_directory == path.join(cwd, 'css'))
        self.assertTrue(settings.docs_directory == path.join(cwd, 'docs'))

        self.assertTrue(settings.file_types == ('*.html', ))

        # test accessibility of true settings
        true_settings = [
            settings.timing_enabled, settings.human_readable, settings.minify, settings.media_queries_enabled,
            settings.use_em
        ]
        for true_setting in true_settings:
            self.assertTrue(true_setting)

        # test accessibility of false settings
        false_settings = [settings.markdown_docs, settings.html_docs, settings.rst_docs]
        for false_setting in false_settings:
            self.assertFalse(false_setting)

        # test base, px_to_em, and breakpoints
        self.assertTrue(settings.base == 16)

        self.assertTrue(settings.xxsmall == (settings.px_to_em(0), settings.px_to_em(120)))
        self.assertTrue(settings.xsmall == (settings.px_to_em(121), settings.px_to_em(240)))
        self.assertTrue(settings.small == (settings.px_to_em(241), settings.px_to_em(480)))
        self.assertTrue(settings.medium == (settings.px_to_em(481), settings.px_to_em(720)))
        self.assertTrue(settings.large == (settings.px_to_em(721), settings.px_to_em(1024)))
        self.assertTrue(settings.xlarge == (settings.px_to_em(1025), settings.px_to_em(1366)))
        self.assertTrue(settings.xxlarge == (settings.px_to_em(1367), settings.px_to_em(1920)))
        self.assertTrue(settings.giant == (settings.px_to_em(1921), settings.px_to_em(2560)))
        self.assertTrue(settings.xgiant == (settings.px_to_em(2561), settings.px_to_em(2800)))
        self.assertTrue(settings.xxgiant == (settings.px_to_em(2801), settings.px_to_em(10**6)))

        # Clean up by deleting test settings file.  Can be commented to see what the generated file looks like.
        # Remove it if it exists.
        if path.isfile(settings_file):
            remove(settings_file)
Beispiel #8
0
    def add_units(self, property_value=''):
        """ If the property_name requires units, then apply the default units defined in default_property_units_dict.

        **Rules:**

        - If use_em is False apply the default units for the property name by looking it up in
          default_property_units_dict.
        - Unit that have default units of ``px`` are converted to ``em`` if use_em is True.
        - If ``property_value`` has multiple property values, then split it apart.
        - If the value already has units, then pass it through unchanged.
        - The value provided shall possess negative signs and decimal points.
        - Mixed units are allowed, but **not recommended**.
        - Values shall only contain [] e.g. -1.25 can be processed, but n1_25 cannot be processed.

        :type property_value: str

        :param property_value: A string containing one or more space delimited alphanumeric characters.
        :return: (str) -- Returns the property value with the default or converted units added.

        >>> # Convert 'px' to 'em'
        >>> unit_parser = UnitParser(property_name='padding', use_em=True)
        >>> unit_parser.add_units('1 2 1 2')
        0.0625em 0.125em 0.0625em 0.125em
        >>> # Use default units
        >>> unit_parser.use_em = False
        >>> unit_parser.add_units('1 2 1 2')
        1px 2px 1px 2px
        >>> # Values already have units or are not parsable pass through
        >>> # True produces the same output.
        >>> unit_parser.use_em = False
        >>> unit_parser.add_units('55zp')
        55zp
        >>> unit_parser.add_units('17rem')
        17rem
        >>> # Unitless ``property_name``
        >>> # causes ``property_value`` to pass through.
        >>> unit_parser.property_name = 'font-weight'
        >>> unit_parser.add_units('200')
        200
        >>> # Mixed units cases - Not a Recommended Practice,
        >>> # but represent valid CSS. Be careful.
        >>> unit_parser.use_em = False
        >>> unit_parser.add_units('5em 6 5em 6')
        5em 6px 5em 6px
        >>> unit_parser.use_em = True
        >>> unit_parser.add_units('1em 100 4cm 9rem')
        1em 6.25em 4cm 9rem

        """
        new_value = []
        try:
            default_units = self.default_property_units_dict[self.property_name]    # See if property_name has units.
            for val in property_value.split():                                      # single, double and quadruple
                if set(val) <= self.allowed:
                    val = val.replace('px', '')                                     # Handle 'px' units case.
                    if settings.use_em and default_units == 'px':                   # Convert units if required.
                        new_value.append(settings.px_to_em(pixels=val))
                    else:
                        new_value.append(val + default_units)                       # Use default units.
                else:                                                               
                    new_value.append(val)                                           # Pass through and ignore value.
            property_value = ' '.join(new_value)                                    # Put the new values back together.
        except KeyError:
            pass                                                                    # Property is unitless.        
        return property_value
    def set_custom_breakpoint_key(self):
        """ Assuming that a limit key is found, but a standard breakpoint key is not found in the ``css_class``;
        determine if a properly formatted custom breakpoint is defined.

        **Custom Breakpoint Rules:**

        - Must begin with an integer.

        - May contain underscores ``_`` to represent decimal points.

        - May end with any allowed unit (em|ex|px|in|cm|mm|pt|pc|q|ch|rem|vw|vh|vmin|vmax).

        - Must not be negative.

        - Unit conversion is based on the related setting in blowdrycss_settings.py.

        **Pattern Explained**

        - ``pattern = r'[a-zA-Z].*\-([0-9]*_?[0-9]*?(em|ex|px|in|cm|mm|pt|pc|q|ch|rem|vw|vh|vmin|vmax)?)\-(up|down)\-?'``

        - ``[a-zA-Z]`` -- css_class must begin with a letter.

        - ``.*`` -- First letter may be followed by any number of characters.

        - ``\-`` -- A dash will appear before the substring pattern.

        - ``([0-9]*_?[0-9]*?(em|ex|px|in|cm|mm|pt|pc|q|ch|rem|vw|vh|vmin|vmax)?)`` -- Substring pattern begins with
          A number that could contain an ``_`` to encode an optional decimal point followed by more numbers.
          Followed by an optional unit of measure.

        - ``\-(up|down)`` -- Substring pattern must end with either ``-up`` or ``-down``.

        - ``\-?`` -- Substring pattern may or may not be followed by a dash since it could be the end of a string or

        :return: None

        **Examples:**

        padding-25-820-up, display-480-down, margin-5-2-5-2-1000-up, display-960-up-i, display-3_2rem-down

        >>> from cssutils.css import Property
        >>> # value='inherit' since we do not know if the class is valid yet.
        >>> name = 'display'
        >>> value = 'inherit'
        >>> priority = ''
        >>> inherit_property = Property(name=name, value=value, priority=priority)
        >>> breakpoint_parser = BreakpointParser(
                css_class='padding-25-820-up',
                css_property=inherit_property
            )
        >>> # BreakpointParser() sets limit_key.
        >>> print(breakpoint_parser.is_breakpoint)
        True
        >>> print(breakpoint_parser.limit_key)
        '-up'
        >>> print(breakpoint_parser.breakpoint_dict[breakpoint_parser.breakpoint_key][breakpoint_parser.limit_key])
        '51.25em'

        """
        pattern = r'[a-zA-Z].*\-([0-9]*_?[0-9]*?(em|ex|px|in|cm|mm|pt|pc|q|ch|rem|vw|vh|vmin|vmax)?)\-(up|down)\-?'
        matches = re.findall(pattern, self.css_class)
        try:
            encoded_breakpoint = matches[0][0]
            self.breakpoint_key = 'custom'
            self.is_breakpoint = True

            # Add the encoded breakpoint to breakpoint_dict with a prepended dash.
            self.breakpoint_dict['custom']['breakpoint'] = '-' + encoded_breakpoint

            # Handle underscore to decimal conversion. (negative values are not permitted)
            custom_breakpoint = encoded_breakpoint.replace('_', '.')

            # Handle unit conversion.
            if use_em:
                custom_breakpoint = px_to_em(custom_breakpoint)

            # Add transformed value to breakpoint_dict
            self.breakpoint_dict['custom'][self.limit_key] = custom_breakpoint
        except IndexError:                      # Pattern not found in css_class
            self.is_breakpoint = False
        except KeyError:                        # Impossible to get here unless the regex pattern fails.
            self.is_breakpoint = False          # Dictionary key problems (excludes '-only' case).