def test_display_without_start(ansi_io):
    bar = ProgressBar(ansi_io, 50, 0)
    bar.display()

    expected = "  0/50 [>---------------------------]   0%"

    assert expected == ansi_io.fetch_error()
def test_finish_without_start(ansi_io):
    bar = ProgressBar(ansi_io, 50, 0)
    bar.finish()

    expected = " 50/50 [============================] 100%"

    assert expected == ansi_io.fetch_error()
def test_non_decorated_output(io):
    bar = ProgressBar(io, 200, 0)
    bar.start()

    for i in range(200):
        bar.advance()

    bar.finish()

    expected = "\n".join(
        [
            "   0/200 [>---------------------------]   0%",
            "  20/200 [==>-------------------------]  10%",
            "  40/200 [=====>----------------------]  20%",
            "  60/200 [========>-------------------]  30%",
            "  80/200 [===========>----------------]  40%",
            " 100/200 [==============>-------------]  50%",
            " 120/200 [================>-----------]  60%",
            " 140/200 [===================>--------]  70%",
            " 160/200 [======================>-----]  80%",
            " 180/200 [=========================>--]  90%",
            " 200/200 [============================] 100%",
        ]
    )

    assert expected == io.fetch_error()
Exemple #4
0
    def _download_archive(self, operation: Install | Update,
                          link: Link) -> Path:
        response = self._authenticator.request("get",
                                               link.url,
                                               stream=True,
                                               io=self._sections.get(
                                                   id(operation), self._io))
        wheel_size = response.headers.get("content-length")
        operation_message = self.get_operation_message(operation)
        message = (
            f"  <fg=blue;options=bold>•</> {operation_message}: <info>Downloading...</>"
        )
        progress = None
        if self.supports_fancy_output():
            if wheel_size is None:
                self._write(operation, message)
            else:
                from cleo.ui.progress_bar import ProgressBar

                progress = ProgressBar(self._sections[id(operation)],
                                       max=int(wheel_size))
                progress.set_format(message + " <b>%percent%%</b>")

        if progress:
            with self._lock:
                self._sections[id(operation)].clear()
                progress.start()

        done = 0
        archive: Path = self._chef.get_cache_directory_for_link(
            link) / link.filename
        archive.parent.mkdir(parents=True, exist_ok=True)
        with archive.open("wb") as f:
            for chunk in response.iter_content(chunk_size=4096):
                if not chunk:
                    break

                done += len(chunk)

                if progress:
                    with self._lock:
                        progress.set_progress(done)

                f.write(chunk)

        if progress:
            with self._lock:
                progress.finish()

        return archive
def test_percent_not_hundred_before_complete(ansi_io):
    bar = ProgressBar(ansi_io, 200, 0)
    bar.start()
    bar.display()
    bar.advance(199)
    bar.advance()

    output = [
        "   0/200 [>---------------------------]   0%",
        " 199/200 [===========================>]  99%",
        " 200/200 [============================] 100%",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
Exemple #6
0
    def progress_bar(self, max: int = 0) -> "ProgressBar":
        """
        Creates a new progress bar
        """
        from cleo.ui.progress_bar import ProgressBar

        return ProgressBar(self._io, max=max)
def test_set_current_progress(ansi_io):
    bar = ProgressBar(ansi_io, 50, 0)
    bar.start()
    bar.display()
    bar.advance()
    bar.set_progress(15)
    bar.set_progress(25)

    output = [
        "  0/50 [>---------------------------]   0%",
        "  1/50 [>---------------------------]   2%",
        " 15/50 [========>-------------------]  30%",
        " 25/50 [==============>-------------]  50%",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
def test_clear(ansi_io):
    bar = ProgressBar(ansi_io, 50, 0)
    bar.start()
    bar.set_progress(25)
    bar.clear()

    output = [
        "  0/50 [>---------------------------]   0%",
        " 25/50 [==============>-------------]  50%",
        "",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
def test_overwrite_with_section_output(ansi_io):
    bar = ProgressBar(ansi_io.section(), 50, 0)
    bar.start()
    bar.display()
    bar.advance()
    bar.advance()

    output = [
        "  0/50 [>---------------------------]   0%",
        "  1/50 [>---------------------------]   2%",
        "  2/50 [=>--------------------------]   4%",
    ]

    expected = "\n\x1b[1A\x1b[0J".join(output) + "\n"

    assert expected == ansi_io.fetch_output()
def test_percent(ansi_io):
    bar = ProgressBar(ansi_io, 50, 0)
    bar.start()
    bar.display()
    bar.advance()
    bar.advance()

    output = [
        "  0/50 [>---------------------------]   0%",
        "  1/50 [>---------------------------]   2%",
        "  2/50 [=>--------------------------]   4%",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
def test_regress_below_min(ansi_io):
    bar = ProgressBar(ansi_io, 10, 0)
    bar.set_progress(1)
    bar.advance(-1)
    bar.advance(-1)

    output = [
        "  1/10 [==>-------------------------]  10%",
        "  0/10 [>---------------------------]   0%",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
def test_advance_over_max(ansi_io):
    bar = ProgressBar(ansi_io, 10)
    bar.set_progress(9)
    bar.advance()
    bar.advance()

    output = [
        "  9/10 [=========================>--]  90%",
        " 10/10 [============================] 100%",
        " 11/11 [============================] 100%",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
Exemple #13
0
    def _upload_file(
        self,
        session: requests.Session,
        url: str,
        file: Path,
        dry_run: bool = False,
        skip_existing: bool = False,
    ) -> None:
        from cleo.ui.progress_bar import ProgressBar

        data = self.post_data(file)
        data.update({
            # action
            ":action": "file_upload",
            "protocol_version": "1",
        })

        data_to_send: list[tuple[str, Any]] = self._prepare_data(data)

        with file.open("rb") as fp:
            data_to_send.append(
                ("content", (file.name, fp, "application/octet-stream")))
            encoder = MultipartEncoder(data_to_send)
            bar = ProgressBar(self._io, max=encoder.len)
            bar.set_format(
                f" - Uploading <c1>{file.name}</c1> <b>%percent%%</b>")
            monitor = MultipartEncoderMonitor(
                encoder, lambda monitor: bar.set_progress(monitor.bytes_read))

            bar.start()

            resp = None

            try:
                if not dry_run:
                    resp = session.post(
                        url,
                        data=monitor,
                        allow_redirects=False,
                        headers={"Content-Type": monitor.content_type},
                        timeout=REQUESTS_TIMEOUT,
                    )
                if resp is None or 200 <= resp.status_code < 300:
                    bar.set_format(
                        f" - Uploading <c1>{file.name}</c1> <fg=green>%percent%%</>"
                    )
                    bar.finish()
                elif resp.status_code == 301:
                    if self._io.output.is_decorated():
                        self._io.overwrite(
                            f" - Uploading <c1>{file.name}</c1> <error>FAILED</>"
                        )
                    raise UploadError("Redirects are not supported. "
                                      "Is the URL missing a trailing slash?")
                elif resp.status_code == 400 and "was ever registered" in resp.text:
                    self._register(session, url)
                    resp.raise_for_status()
                elif skip_existing and self._is_file_exists_error(resp):
                    bar.set_format(
                        f" - Uploading <c1>{file.name}</c1> <warning>File exists."
                        " Skipping</>")
                    bar.display()
                else:
                    resp.raise_for_status()
            except (requests.ConnectionError, requests.HTTPError) as e:
                if self._io.output.is_decorated():
                    self._io.overwrite(
                        f" - Uploading <c1>{file.name}</c1> <error>FAILED</>")
                raise UploadError(e)
            finally:
                self._io.write_line("")
Exemple #14
0
    def _upload_file(
        self,
        session: requests.Session,
        url: str,
        file: Path,
        dry_run: Optional[bool] = False,
    ) -> requests.Response:
        from cleo.ui.progress_bar import ProgressBar

        data = self.post_data(file)
        data.update({
            # action
            ":action": "file_upload",
            "protocol_version": "1",
        })

        data_to_send = self._prepare_data(data)

        with file.open("rb") as fp:
            data_to_send.append(
                ("content", (file.name, fp, "application/octet-stream")))
            encoder = MultipartEncoder(data_to_send)
            bar = ProgressBar(self._io, max=encoder.len)
            bar.set_format(
                f" - Uploading <c1>{file.name}</c1> <b>%percent%%</b>")
            monitor = MultipartEncoderMonitor(
                encoder, lambda monitor: bar.set_progress(monitor.bytes_read))

            bar.start()

            resp = None

            try:
                if not dry_run:
                    resp = session.post(
                        url,
                        data=monitor,
                        allow_redirects=False,
                        headers={"Content-Type": monitor.content_type},
                    )
                if dry_run or 200 <= resp.status_code < 300:
                    bar.set_format(
                        f" - Uploading <c1>{file.name}</c1> <fg=green>%percent%%</>"
                    )
                    bar.finish()
                elif resp.status_code == 301:
                    if self._io.output.is_decorated():
                        self._io.overwrite(
                            f" - Uploading <c1>{file.name}</c1> <error>FAILED</>"
                        )
                    raise UploadError("Redirects are not supported. "
                                      "Is the URL missing a trailing slash?")
            except (requests.ConnectionError, requests.HTTPError) as e:
                if self._io.output.is_decorated():
                    self._io.overwrite(
                        f" - Uploading <c1>{file.name}</c1> <error>FAILED</>")
                raise UploadError(e)
            finally:
                self._io.write_line("")

        return resp
def test_overwrite_multiple_progress_bars_with_section_outputs(ansi_io):
    output1 = ansi_io.section()
    output2 = ansi_io.section()

    bar1 = ProgressBar(output1, 50, 0)
    bar2 = ProgressBar(output2, 50, 0)

    bar1.start()
    bar2.start()

    bar2.advance()
    bar1.advance()

    output = [
        "  0/50 [>---------------------------]   0%",
        "  0/50 [>---------------------------]   0%",
        "\x1b[1A\x1b[0J  1/50 [>---------------------------]   2%",
        "\x1b[2A\x1b[0J  1/50 [>---------------------------]   2%",
        "\x1b[1A\x1b[0J  1/50 [>---------------------------]   2%",
        "  1/50 [>---------------------------]   2%",
    ]

    expected = "\n".join(output) + "\n"

    assert expected == ansi_io.fetch_output()
def test_multiline_format(ansi_io):
    bar = ProgressBar(ansi_io, 3, 0)
    bar.set_format("%bar%\nfoobar")

    bar.start()
    bar.advance()
    bar.clear()
    bar.finish()

    output = [
        ">---------------------------\nfoobar",
        "=========>------------------\nfoobar",
        "\n",
        "============================\nfoobar",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
def bar(io):
    return ProgressBar(io, min_seconds_between_redraws=0)
def test_format(ansi_io):
    output = [
        "  0/10 [>---------------------------]   0%",
        " 10/10 [============================] 100%",
    ]

    expected = generate_output(output)

    # max in construct, no format
    ansi_io.clear_error()
    bar = ProgressBar(ansi_io, 10)
    bar.start()
    bar.advance(10)
    bar.finish()

    assert expected == ansi_io.fetch_error()

    # max in start, no format
    ansi_io.clear_error()
    bar = ProgressBar(ansi_io)
    bar.start(10)
    bar.advance(10)
    bar.finish()

    assert expected == ansi_io.fetch_error()

    # max in construct, explicit format before
    ansi_io.clear_error()
    bar = ProgressBar(ansi_io, 10)
    bar.set_format("normal")
    bar.start()
    bar.advance(10)
    bar.finish()

    assert expected == ansi_io.fetch_error()

    # max in start, explicit format before
    ansi_io.clear_error()
    bar = ProgressBar(ansi_io)
    bar.set_format("normal")
    bar.start(10)
    bar.advance(10)
    bar.finish()

    assert expected == ansi_io.fetch_error()
def ansi_bar(ansi_io):
    return ProgressBar(ansi_io, min_seconds_between_redraws=0)
def test_customizations(ansi_io):
    bar = ProgressBar(ansi_io, 10, 0)
    bar.set_bar_width(10)
    bar.set_bar_character("_")
    bar.set_empty_bar_character(" ")
    bar.set_progress_character("/")
    bar.set_format(" %current%/%max% [%bar%] %percent:3s%%")
    bar.start()
    bar.advance()

    output = ["  0/10 [/         ]   0%", "  1/10 [_/        ]  10%"]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()
def test_display_with_quiet_verbosity(ansi_io):
    ansi_io.set_verbosity(Verbosity.QUIET)
    bar = ProgressBar(ansi_io, 50, 0)
    bar.display()

    assert "" == ansi_io.fetch_error()
def test_overwrite_with_shorter_line(ansi_io):
    bar = ProgressBar(ansi_io, 50, 0)
    bar.set_format(" %current%/%max% [%bar%] %percent:3s%%")
    bar.start()
    bar.display()
    bar.advance()

    # Set shorter format
    bar.set_format(" %current%/%max% [%bar%]")
    bar.advance()

    output = [
        "  0/50 [>---------------------------]   0%",
        "  1/50 [>---------------------------]   2%",
        "  2/50 [=>--------------------------]",
    ]

    expected = generate_output(output)

    assert expected == ansi_io.fetch_error()