Skip to content

Conversation

P1otrulla
Copy link
Member

@P1otrulla P1otrulla commented Aug 26, 2025

podstawka pod eternalcombat i na własny użytek

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @P1otrulla, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces two new utility classes: ProgressBar for generating customizable text-based progress bars and SimpleDurationUtil for formatting java.time.Duration objects into human-readable strings. These additions enhance the eternalcode-commons-shared library by providing common, reusable components for UI representation and time handling.

Highlights

  • ProgressBar Implementation: A new ProgressBar class has been added, allowing developers to create visual progress indicators. It supports customization of filled and empty characters, colors, length, and bracket display, and provides methods to render progress based on double, int, or long values.
  • Duration Formatting Utility: The SimpleDurationUtil class provides static methods to format java.time.Duration instances. It includes options to format durations with or without milliseconds, converting them into concise strings like "5m", "2h", or "120ms".
  • Comprehensive Unit Tests: Both new utility classes are accompanied by dedicated JUnit 5 test classes (ProgressBarTest.java and SimpleDurationUtilTest.java), ensuring the correctness and robustness of their functionalities, including edge cases like zero or negative inputs and custom configurations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@P1otrulla P1otrulla changed the title GH-0 Progessbar GH-57 Add Progessbar Aug 26, 2025
@P1otrulla P1otrulla added 🆕 feature New feature or request 🆕 good first issue Good for newcomers labels Aug 26, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces two new utilities, ProgressBar and SimpleDurationUtil, along with their corresponding tests. The overall implementation is good, but there are several areas for improvement regarding code clarity, performance, and test quality. I've provided suggestions to refactor the ProgressBar for better readability and efficiency, and for SimpleDurationUtil, I've recommended making it a proper utility class and using more idiomatic Duration comparison. Additionally, the tests for both utilities could be enhanced by using more specific assertions and employing parameterized tests to reduce code duplication.

import java.time.temporal.ChronoUnit;

public class SimpleDurationUtil {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since this is a utility class with only static members, it's a good practice to add a private constructor to prevent it from being instantiated.

Suggested change
private SimpleDurationUtil() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}


public static String format(Duration duration, boolean removeMillis) {
if (removeMillis) {
if (duration.toMillis() < ONE_SECOND.toMillis()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For comparing Duration objects, it's more idiomatic and readable to use the compareTo method instead of comparing their millisecond values.

Suggested change
if (duration.toMillis() < ONE_SECOND.toMillis()) {
if (duration.compareTo(ONE_SECOND) < 0) {

Comment on lines +16 to +18
assertTrue(rendered.contains("█"));
assertFalse(rendered.contains("░"));
assertEquals(7, rendered.length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assertions in this test can be more specific. Instead of checking for character containment and length separately, you can assert the exact expected string. This makes the test more robust and clearly states the expected outcome.

Suggested change
assertTrue(rendered.contains("█"));
assertFalse(rendered.contains("░"));
assertEquals(7, rendered.length());
assertEquals("[█████]", rendered);

Comment on lines +28 to +30
assertTrue(rendered.contains("░"));
assertFalse(rendered.contains("█"));
assertEquals(7, rendered.length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To make this test more robust and clear, consider asserting against the exact expected string instead of checking for character containment and length.

Suggested change
assertTrue(rendered.contains("░"));
assertFalse(rendered.contains("█"));
assertEquals(7, rendered.length());
assertEquals("[░░░░░]", rendered);

Comment on lines +40 to +42
assertTrue(rendered.contains("█"));
assertTrue(rendered.contains("░"));
assertEquals(6, rendered.length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assertions here can be made more specific by checking for the exact expected string. This improves the test's clarity and robustness.

Suggested change
assertTrue(rendered.contains("█"));
assertTrue(rendered.contains("░"));
assertEquals(6, rendered.length());
assertEquals("[██░░]", rendered);

Comment on lines +9 to +10
@Test
public void testFormatWithoutMillis() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In JUnit 5, test methods are no longer required to be public. You can make them package-private (default visibility) to reduce verbosity. This applies to all test methods in this class.

Suggested change
@Test
public void testFormatWithoutMillis() {
@Test
void testFormatWithoutMillis() {

Comment on lines +9 to +77
@Test
public void testFormatWithoutMillis() {
Duration duration = Duration.ofMillis(500);
String result = SimpleDurationUtil.format(duration, true);
assertEquals("0s", result);

duration = Duration.ofSeconds(30);
result = SimpleDurationUtil.format(duration, true);
assertEquals("30s", result);

duration = Duration.ofMinutes(5);
result = SimpleDurationUtil.format(duration, true);
assertEquals("5m", result);

duration = Duration.ofHours(2);
result = SimpleDurationUtil.format(duration, true);
assertEquals("2h", result);

duration = Duration.ofDays(1);
result = SimpleDurationUtil.format(duration, true);
assertEquals("1d", result);

duration = Duration.ofDays(14);
result = SimpleDurationUtil.format(duration, true);
assertEquals("2w", result);

duration = Duration.ofDays(60);
result = SimpleDurationUtil.format(duration, true);
assertEquals("2mo", result);

duration = Duration.ofDays(365 * 3);
result = SimpleDurationUtil.format(duration, true);
assertEquals("3y", result);
}

@Test
public void testFormatWithMillis() {
Duration duration = Duration.ofMillis(500);
String result = SimpleDurationUtil.format(duration, false);
assertEquals("500ms", result);

duration = Duration.ofSeconds(30);
result = SimpleDurationUtil.format(duration, false);
assertEquals("30s", result);

duration = Duration.ofMinutes(5);
result = SimpleDurationUtil.format(duration, false);
assertEquals("5m", result);

duration = Duration.ofHours(2);
result = SimpleDurationUtil.format(duration, false);
assertEquals("2h", result);

duration = Duration.ofDays(1);
result = SimpleDurationUtil.format(duration, false);
assertEquals("1d", result);

duration = Duration.ofDays(14);
result = SimpleDurationUtil.format(duration, false);
assertEquals("2w", result);

duration = Duration.ofDays(60);
result = SimpleDurationUtil.format(duration, false);
assertEquals("2mo", result);

duration = Duration.ofDays(365 * 3);
result = SimpleDurationUtil.format(duration, false);
assertEquals("3y", result);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The test methods testFormatWithoutMillis and testFormatWithMillis contain a lot of repetitive code. Consider using JUnit 5's parameterized tests (@ParameterizedTest) to make them more concise, easier to maintain, and simpler to extend with new test cases.

Here's an example of how you could refactor testFormatWithoutMillis:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

// ...

    @ParameterizedTest
    @CsvSource({
        "PT0.5S, 0s",      // 500 ms
        "PT30S, 30s",
        "PT5M, 5m",
        "PT2H, 2h",
        "P1D, 1d",
        "P14D, 2w",
        "P60D, 2mo",
        "P1095D, 3y"      // 3 * 365 days
    })
    void testFormatWithoutMillis(Duration duration, String expected) {
        String result = SimpleDurationUtil.format(duration, true);
        assertEquals(expected, result);
    }

You would need to add the org.junit.jupiter:junit-jupiter-params dependency if it's not already in your project. The same refactoring can be applied to testFormatWithMillis and testFormatDefault.

…ns/progressbar/ProgressBar.java

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@P1otrulla P1otrulla closed this Aug 26, 2025
@P1otrulla P1otrulla deleted the progessbar branch August 26, 2025 01:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🆕 feature New feature or request 🆕 good first issue Good for newcomers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant