def test_normal_number_5(self):
        col_dp = ColumnDataProperty()
        col_dp.update_header(DataProperty("abc"))

        for value in [1.1, 2.2, 3.33]:
            col_dp.update_body(DataProperty(value))

        assert col_dp.align == Align.RIGHT
        assert col_dp.decimal_places == 2
        assert col_dp.typecode == Typecode.REAL_NUMBER
        assert col_dp.ascii_char_width == 4

        assert col_dp.minmax_integer_digits.min_value == 1
        assert col_dp.minmax_integer_digits.max_value == 1

        assert col_dp.minmax_decimal_places.min_value == 1
        assert col_dp.minmax_decimal_places.max_value == 2
        assert col_dp.minmax_additional_format_len.min_value == 0
        assert col_dp.minmax_additional_format_len.max_value == 0

        assert text_type(col_dp) == (
            "type=REAL_NUMBER, align=right, ascii_width=4, "
            "int_digits=1, decimal_places=(min=1, max=2)")
    def test_normal_inf(self):
        col_dp = ColumnDataProperty()
        col_dp.update_header(DataProperty("inf"))

        for value in [inf, None, inf, "inf"]:
            col_dp.update_body(DataProperty(value))

        assert col_dp.align == Align.LEFT
        assert col_dp.decimal_places is None
        assert col_dp.typecode == Typecode.INFINITY
        assert col_dp.ascii_char_width == 8

        assert col_dp.minmax_integer_digits.min_value is None
        assert col_dp.minmax_integer_digits.max_value is None

        assert col_dp.minmax_decimal_places.min_value is None
        assert col_dp.minmax_decimal_places.max_value is None

        assert col_dp.minmax_additional_format_len.min_value == 0
        assert col_dp.minmax_additional_format_len.max_value == 0

        assert text_type(col_dp) == (
            "type=INFINITY, align=left, ascii_width=8")
    def test_normal_east_asian_ambiguous_width(self, ambiguous_width,
                                               ascii_char_width):
        col_dp = ColumnDataProperty(east_asian_ambiguous_width=ambiguous_width)
        col_dp.update_header(DataProperty("abc"))

        for value in ["ØØØ", "α", "ββ"]:
            col_dp.update_body(
                DataProperty(value,
                             east_asian_ambiguous_width=ambiguous_width))

        assert col_dp.align == Align.LEFT
        assert col_dp.decimal_places is None
        assert col_dp.typecode == Typecode.STRING
        assert col_dp.ascii_char_width == ascii_char_width

        assert col_dp.minmax_integer_digits.min_value is None
        assert col_dp.minmax_integer_digits.max_value is None

        assert col_dp.minmax_decimal_places.min_value is None
        assert col_dp.minmax_decimal_places.max_value is None

        assert col_dp.minmax_additional_format_len.min_value == 0
        assert col_dp.minmax_additional_format_len.max_value == 0
def _validate_within_min_max(param_name, value, min_value, max_value, unit):
    if value is None:
        return

    if unit is None:
        unit = ""
    else:
        unit = "[{:s}]".format(unit)

    if value > max_value:
        raise InvalidParameterError("'{:s}' is too high".format(param_name),
                                    expected="<={:s}{:s}".format(
                                        DataProperty(max_value).to_str(),
                                        unit),
                                    value="{:s}{:s}".format(
                                        DataProperty(value).to_str(), unit))

    if value < min_value:
        raise InvalidParameterError("'{:s}' is too low".format(param_name),
                                    expected=">={:s}{:s}".format(
                                        DataProperty(min_value).to_str(),
                                        unit),
                                    value="{:s}{:s}".format(
                                        DataProperty(value).to_str(), unit))
Beispiel #5
0
    def test_normal_number_4(self):
        col_dp = ColumnDataProperty()
        col_dp.update_header(DataProperty("abc"))

        for value in [0.01, 1.0, 1.2]:
            col_dp.update_body(DataProperty(value))

        assert col_dp.align == Align.RIGHT
        assert col_dp.decimal_places == 2
        assert col_dp.typecode == Typecode.REAL_NUMBER
        assert col_dp.ascii_char_width == 4

        assert col_dp.minmax_integer_digits.min_value == 1
        assert col_dp.minmax_integer_digits.max_value == 1

        assert col_dp.minmax_decimal_places.min_value == 0
        assert col_dp.minmax_decimal_places.max_value == 2
        assert col_dp.minmax_additional_format_len.min_value == 0
        assert col_dp.minmax_additional_format_len.max_value == 0

        assert str(col_dp) == (
            "typename=REAL_NUMBER, align=right, ascii_char_width=4, "
            "integer_digits=(min=1, max=1), decimal_places=(min=0, max=2), "
            "additional_format_len=(min=0, max=0)")
Beispiel #6
0
 def test_abnormal(self, value, expected):
     dp = DataProperty(value)
     Nan(dp.length).is_type()
Beispiel #7
0
    def test_normal_eaaw(self, value, eaaw, expected_acs, expected_len):
        dp = DataProperty(value, east_asian_ambiguous_width=eaaw)

        assert dp.ascii_char_width == expected_acs
        assert dp.length == expected_len
Beispiel #8
0
    def test_normal(self, value, expected_acs, expected_len):
        dp = DataProperty(value)

        assert dp.ascii_char_width == expected_acs
        assert dp.length == expected_len
Beispiel #9
0
 def test_normal(self, value, expected):
     dp = DataProperty(value)
     assert dp.align == expected
Beispiel #10
0
    def test_normal_tab(self, value, is_escape_html_tag, expected):
        dp = DataProperty(value, is_escape_html_tag=is_escape_html_tag)

        assert dp.data == expected
Beispiel #11
0
 def test_smoke(self, value, strict_type_mapping, expected):
     dp = DataProperty(value, strict_type_mapping=strict_type_mapping)
     assert len(dp.__repr__()) > expected
Beispiel #12
0
    def test_normal(self, lhs, rhs, expected):
        lhs = DataProperty(lhs)
        rhs = DataProperty(rhs)

        assert (lhs == rhs) == expected
        assert (lhs != rhs) == (not expected)
Beispiel #13
0
 def test_abnormal(self, value):
     dp = DataProperty(value)
     Nan(dp.integer_digits).is_type()
Beispiel #14
0
 def test_normal_east_asian_ambiguous_width(self, value, ascii_char_width,
                                            ambiguous_width, expected):
     dp = DataProperty(value, east_asian_ambiguous_width=ambiguous_width)
     assert dp.get_padding_len(ascii_char_width) == expected
Beispiel #15
0
    def test_normal_ascii_escape_sequence(self, value, expected_acw,
                                          expected_len):
        dp = DataProperty(value)

        assert dp.ascii_char_width == expected_acw
        assert dp.length == expected_len
Beispiel #16
0
 def test_normal(self, value, expected_acw):
     assert DataProperty(value).is_include_ansi_escape == expected_acw
Beispiel #17
0
 def test_smoke(self, value, strict_level_map, expected):
     dp = DataProperty(value, strict_level_map=strict_level_map)
     assert len(dp.__repr__()) > expected
Beispiel #18
0
 def test_exception_eaaw(self, value, eaaw, expected):
     with pytest.raises(expected):
         DataProperty(value, east_asian_ambiguous_width=eaaw)
Beispiel #19
0
 def test_abnormal(self, value):
     dp = DataProperty(value)
     Nan(dp.decimal_places).is_type()
Beispiel #20
0
 def test_normal(self, value, ascii_char_width, expected):
     dp = DataProperty(value)
     assert dp.get_padding_len(ascii_char_width) == expected
Beispiel #21
0
 def test_normal(self, value, line_break_handling, expected):
     assert DataProperty(
         value, line_break_handling=line_break_handling).data == expected
Beispiel #22
0
 def test_normal(self, value, expected):
     dp = DataProperty(value)
     assert dp.integer_digits == expected
Beispiel #23
0
class JavaScriptTableWriter(SourceCodeTableWriter):
    """
    A table writer for class JavaScript format.

        :Example:
            :ref:`example-js-table-writer`

    .. py:attribute:: variable_declaration
        :type: str
        :value: "const"

        JavaScript variable declarations type.
        The value must be either ``"var"``, ``"let"`` or ``"const"``.

    .. py:method:: write_table

        |write_table| with JavaScript format.
        The tabular data are written as a nested list variable definition.

        :raises pytablewriter.EmptyTableNameError:
            If the |table_name| is empty.
        :Example:
            :ref:`example-js-table-writer`

        .. note::
            Specific values in the tabular data are converted when writing:

            - |None|: written as ``null``
            - |inf|: written as ``Infinity``
            - |nan|: written as ``NaN``
            - |datetime| instances determined by |is_datetime_instance_formatting| attribute:
                - |True|: written as `dateutil.parser <https://dateutil.readthedocs.io/en/stable/parser.html>`__
                - |False|: written as |str|

            .. seealso::
                :ref:`example-type-hint-js`
    """

    FORMAT_NAME = "javascript"
    __VALID_VAR_DECLARATION = ("var", "let", "const")
    __NONE_VALUE_DP = DataProperty("null")

    @property
    def format_name(self) -> str:
        return self.FORMAT_NAME

    @property
    def support_split_write(self) -> bool:
        return True

    @property
    def variable_declaration(self) -> str:
        return self.__variable_declaration

    @variable_declaration.setter
    def variable_declaration(self, value: str):
        value = value.strip().casefold()
        if value not in self.__VALID_VAR_DECLARATION:
            raise ValueError("declaration must be either var, let or const")

        self.__variable_declaration = value

    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)

        self.variable_declaration = "const"
        self._dp_extractor.type_value_map = {
            # Typecode.NONE: "null",
            Typecode.INFINITY: "Infinity",
            Typecode.NAN: "NaN",
        }
        self._dp_extractor.update_strict_level_map(
            {Typecode.BOOL: StrictLevel.MAX})
        self.register_trans_func(bool_to_str)

    def get_variable_name(self, value: str) -> str:
        return sanitize_js_var_name(value, "_").casefold()

    def _write_table(self, **kwargs) -> None:
        if self.is_datetime_instance_formatting:
            self._dp_extractor.datetime_formatter = js_datetime_formatter
        else:
            self._dp_extractor.datetime_formatter = quote_datetime_formatter

        org_stream = self.stream
        self.stream = io.StringIO()

        self.inc_indent_level()
        super()._write_table(**kwargs)
        self.dec_indent_level()
        js_matrix_var_def_text = self.stream.getvalue().rstrip("\n")
        js_matrix_var_def_text = strip_quote(js_matrix_var_def_text, "true")
        js_matrix_var_def_text = strip_quote(js_matrix_var_def_text, "false")
        if self.is_write_closing_row:
            js_matrix_var_def_line_list = js_matrix_var_def_text.splitlines()
            js_matrix_var_def_line_list[-2] = js_matrix_var_def_line_list[
                -2].rstrip(",")
            js_matrix_var_def_text = "\n".join(js_matrix_var_def_line_list)

        self.stream.close()
        self.stream = org_stream

        self.dec_indent_level()
        self._write_line(js_matrix_var_def_text)
        self.inc_indent_level()

    def _get_opening_row_items(self) -> List[str]:
        return [
            "{:s} {:s} = [".format(self.variable_declaration,
                                   self.variable_name)
        ]

    def _get_closing_row_items(self) -> List[str]:
        return ["];"]

    def _to_row_item(self, row_idx: int, col_dp: ColumnDataProperty,
                     value_dp: DataProperty) -> str:
        if value_dp.data is None:
            value_dp = self.__NONE_VALUE_DP

        return super()._to_row_item(row_idx, col_dp, value_dp)
Beispiel #24
0
 def test_normal(self, value, expected):
     dp = DataProperty(value)
     assert dp.decimal_places == expected
Beispiel #25
0
class JavaScriptTableWriter(SourceCodeTableWriter):
    """
    A table writer for class JavaScript format.

    .. py:attribute:: variable_declaration

        JavaScript variable declarations type.
        The value must be either ``"var"``, ``"let"`` or ``"const"``.
        Defaults to ``"const"``.

    .. py:method:: write_table

        |write_table| with JavaScript format.
        The tabular data are written as a nested list variable definition.

        :raises pytablewriter.EmptyTableNameError:
            If the |table_name| is empty.
        :raises pytablewriter.EmptyTableDataError:
            If the |header_list| and the |value_matrix| is empty.
        :Example:
            :ref:`example-js-table-writer`

        .. note::
            Specific values in the tabular data are converted when writing:

            - |None|: written as ``null``
            - |inf|: written as ``Infinity``
            - |nan|: written as ``NaN``
            - |datetime| instances determined by |is_datetime_instance_formatting| attribute:
                - |True|: written as `dateutil.parser <https://dateutil.readthedocs.io/en/stable/parser.html>`__
                - |False|: written as |str|

            .. seealso::
                :ref:`example-type-hint-js`
    """

    __VALID_VAR_DECLARATION = ("var", "let", "const")
    __NONE_VALUE_DP = DataProperty("null")

    @property
    def format_name(self):
        return "javascript"

    @property
    def support_split_write(self):
        return True

    @property
    def variable_declaration(self):
        return self.__variable_declaration

    @variable_declaration.setter
    def variable_declaration(self, value):
        value = value.strip().lower()
        if value not in self.__VALID_VAR_DECLARATION:
            raise ValueError("declaration must be either var, let or const")

        self.__variable_declaration = value

    def __init__(self):
        super(JavaScriptTableWriter, self).__init__()

        self.variable_declaration = "const"
        self._dp_extractor.type_value_map = {
            # Typecode.NONE: "null",
            Typecode.INFINITY: "Infinity",
            Typecode.NAN: "NaN",
        }
        self._dp_extractor.const_value_map = {True: "true", False: "false"}

    def get_variable_name(self, value):
        import pathvalidate

        return pathvalidate.sanitize_js_var_name(value, "_").lower()

    def _write_table(self):
        if self.is_datetime_instance_formatting:
            self._dp_extractor.datetime_formatter = js_datetime_formatter
        else:
            self._dp_extractor.datetime_formatter = quote_datetime_formatter

        self._preprocess()

        org_stream = self.stream
        self.stream = six.StringIO()

        self.inc_indent_level()
        super(JavaScriptTableWriter, self)._write_table()
        self.dec_indent_level()
        js_matrix_var_def_text = self.stream.getvalue().rstrip("\n")
        if self.is_write_closing_row:
            js_matrix_var_def_line_list = js_matrix_var_def_text.splitlines()
            js_matrix_var_def_line_list[-2] = js_matrix_var_def_line_list[
                -2].rstrip(",")
            js_matrix_var_def_text = "\n".join(js_matrix_var_def_line_list)

        self.stream.close()
        self.stream = org_stream

        self.dec_indent_level()
        self._write_line(js_matrix_var_def_text)
        self.inc_indent_level()

    def _get_opening_row_item_list(self):
        return [
            "{:s} {:s} = [".format(self.variable_declaration,
                                   self.variable_name)
        ]

    def _get_closing_row_item_list(self):
        return ["];"]

    def _to_row_item(self, col_dp, value_dp):
        if value_dp.data is None:
            value_dp = self.__NONE_VALUE_DP

        return super(JavaScriptTableWriter,
                     self)._to_row_item(col_dp, value_dp)
Beispiel #26
0
 def test_normal(self, value, expected):
     dp = DataProperty(value)
     assert dp.additional_format_len == expected
Beispiel #27
0
    def test_normal_tab(self, value, float_type, expected):
        dp = DataProperty(value, float_type=float_type)

        assert isinstance(dp.data, float_type)
        assert dp.data == expected
Beispiel #28
0
    def test_normal(self, value, expected_data, expected_typecode):
        dp = DataProperty(value)

        assert dp == dp
        assert dp.data == expected_data
        assert dp.typecode == expected_typecode
Beispiel #29
0
    def test_normal_format_str(self, value, format_flags, expected):
        dp = DataProperty(value, format_flags=format_flags)

        assert dp.to_str() == expected