Skip to content

[TASK-6560] + [TASK-6688] fix: update formatAmount function #583

Merged
Hugo0 merged 9 commits intodevelopfrom
fix/amount-formatting
Dec 27, 2024
Merged

[TASK-6560] + [TASK-6688] fix: update formatAmount function #583
Hugo0 merged 9 commits intodevelopfrom
fix/amount-formatting

Conversation

@kushagrasarathe
Copy link
Contributor

@kushagrasarathe kushagrasarathe commented Dec 19, 2024

  • updated the formatAmount function to handle multiple while formatting the amount
  • updated the pay-request and link preview to use this updated funciton

Summary by CodeRabbit

  • New Features

    • Enhanced amount formatting across components for improved clarity and consistency.
  • Bug Fixes

    • Corrected the function name from delteFromLocalStorage to deleteFromLocalStorage.
  • Chores

    • Updated the formatAmount function to handle various input types and improve error handling, including better management of small decimal numbers.
    • Introduced a comprehensive test suite for the formatAmount function to ensure robust performance across various scenarios.
    • Added mock data for blockchain networks to facilitate testing and development.

@vercel
Copy link

vercel bot commented Dec 19, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
peanut-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 27, 2024 10:55am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2024

Walkthrough

The pull request introduces modifications to amount formatting across multiple files. The primary change is the introduction of a new formatAmount function in general.utils.ts that provides more robust handling of numeric inputs. This function replaces previous token-specific formatting methods in components like LinkPreview.tsx and Initial.view.tsx. The changes aim to standardize and improve the way monetary amounts are displayed throughout the application, with enhanced error handling and more flexible decimal place management.

Changes

File Change Summary
src/components/Global/ImageGeneration/LinkPreview.tsx Replaced utils.formatTokenAmount(parseFloat(amount), 2) with utils.formatAmount(amount) for amount display; changed font size from 49px to 24px.
src/components/Request/Pay/Views/Initial.view.tsx Updated amount formatting from formatAmountWithSignificantDigits() to formatAmount() for requested and token amounts.
src/utils/general.utils.ts Completely rewrote formatAmount() to handle string/number inputs, added comprehensive error handling for undefined/null/empty inputs, and improved decimal rounding logic. Corrected function name from delteFromLocalStorage to deleteFromLocalStorage.
src/utils/__tests__/general.utils.test.ts Added a comprehensive test suite for formatAmount() covering various scenarios including edge cases, small numbers, regular numbers, and whole numbers.
package.json Added jest-transform-stub as a dev dependency; updated Jest configuration to support ECMAScript modules and added new test matching patterns.
src/utils/__mocks__/peanut-sdk.ts Introduced CHAIN_DETAILS and TOKEN_DETAILS constants for mock data related to blockchain networks.
src/utils/__mocks__/wagmi.ts Added mock objects for mainnet and sepolia blockchain networks for testing purposes.

Possibly related PRs

Suggested reviewers

  • jjramirezn

Poem

🐰 A rabbit's tale of numbers bright,
Formatting amounts with all my might!
From tokens small to figures grand,
My code now dances, perfectly planned!
Decimals rounded, errors at bay,
Precision is my coding way! 🧮✨

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1ef36aa and 0fb46f7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • package.json (2 hunks)
  • src/utils/__mocks__/peanut-sdk.ts (1 hunks)
  • src/utils/__mocks__/wagmi.ts (1 hunks)
🔇 Additional comments (9)
src/utils/__mocks__/wagmi.ts (2)

1-14: Good consistency in defining the Ethereum mainnet mocks.

These details seem aligned with standard Ethereum mainnet configs. The structured format for nativeCurrency and rpcUrls is consistent and will simplify referencing in tests.


16-28: Appropriate separation of mainnet and testnet mock data.

Using a separate constant for Sepolia ensures better clarity when mocking different chains in tests. The structure mirrors mainnet, which fosters consistency.

src/utils/__mocks__/peanut-sdk.ts (2)

1-15: Clear separation of chain IDs with relevant properties.

The object structure under CHAIN_DETAILS is straightforward, making it easy to extend for additional test or production networks. This approach streamlines test scenarios by providing realistic environment data.


17-34: Accurate representation of token details.

Defining token metadata (like symbol, name, and decimals) clearly for each chain is a good practice. It’s beneficial that you’re using the zero address (0x0000...) for test tokens, highlighting their mock nature.

package.json (5)

85-85: Helpful dependency for stubbing static assets in tests.

jest-transform-stub is particularly useful for ignoring non-code assets like CSS or images, preventing test failures. Great addition for a more robust testing setup.


102-103: Adoption of ESM in Jest transform.

Setting "useESM": true helps you run TypeScript test files in ESM mode. This is a forward-looking approach as ESM usage grows. Verify that all test files and imports remain compatible under ESM.


108-108: Fine-tuning transformIgnorePatterns.

Allowing transformation of modules under @squirrel-labs ensures you can properly mock or transform them for testing. Confirm this pattern doesn’t inadvertently process large or unnecessary modules, impacting test performance.


111-113: Module name mappings for custom mocks.

Redirecting imports of wagmi/chains and @squirrel-labs/peanut-sdk to their respective mock files is well-organized. This pattern fosters easier tests and consistent data injection.


121-124: Ensuring .ts/.tsx files are treated as ESM.

Listing these extensions is crucial for consistent ESM behavior in test environments, particularly when dealing with modern JavaScript features. This is a solid step for ensuring TypeScript ESM compatibility.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@notion-workspace
Copy link

@notion-workspace
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/utils/general.utils.ts (1)

234-284: Well-documented and robust number formatting implementation.

The implementation is thorough and handles various edge cases effectively:

  • Comprehensive input validation
  • Special handling for small numbers
  • Intelligent trailing zero removal
  • Clear documentation with examples

Consider adding example inputs and outputs in the JSDoc comments to make the behavior more explicit:

 /**
  * formats a number by removing unnecessary trailing zeros after decimal point
  * if all decimal places are zeros, returns the whole number
  * preserves small decimal numbers
  * @param amount - number or string to format
  * @returns formatted string representation of the number
+ * @example
+ * formatAmount("123.4500") => "123.45"
+ * formatAmount(0.00123) => "0.00123"
+ * formatAmount("123.00") => "123"
  */
🧰 Tools
🪛 Biome (1.9.4)

[error] 249-249: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8cd19c and a93e79b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • src/components/Global/ImageGeneration/LinkPreview.tsx (1 hunks)
  • src/components/Request/Pay/Views/Initial.view.tsx (4 hunks)
  • src/utils/general.utils.ts (1 hunks)
🧰 Additional context used
📓 Learnings (2)
src/components/Global/ImageGeneration/LinkPreview.tsx (1)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#460
File: src/components/Global/ImageGeneration/LinkPreview.tsx:125-128
Timestamp: 2024-11-12T09:39:20.720Z
Learning: 'tokenPrice' is not used currently and will be removed in future PRs.
src/components/Request/Pay/Views/Initial.view.tsx (3)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-11-12T09:39:20.720Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(estimatedGasCost, 3)` return strings, ensuring consistent return types for `calculatedFee`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-11-12T09:39:20.720Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(...)` return strings, ensuring that `calculatedFee` consistently returns a string without the need for additional type conversion.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#410
File: src/components/Request/Pay/Views/Initial.view.tsx:87-93
Timestamp: 2024-11-12T09:39:20.720Z
Learning: When refactoring to eliminate code duplication, prioritize readability and consider whether the change significantly improves the code. If it doesn't enhance readability or maintainability, it's acceptable to keep the existing code structure.
🪛 Biome (1.9.4)
src/utils/general.utils.ts

[error] 249-249: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

🔇 Additional comments (3)
src/components/Global/ImageGeneration/LinkPreview.tsx (1)

136-136: LGTM! Appropriate usage of formatAmount.

The change correctly adopts the new formatAmount function while maintaining the parseFloat conversion for type safety.

src/components/Request/Pay/Views/Initial.view.tsx (2)

23-23: LGTM! Consistent adoption of formatAmount.

The import and usage of formatAmount is consistent with the PR objectives. The conditional formatting for USD and token amounts is handled appropriately.

Also applies to: 124-126


358-358: LGTM! Display formatting is consistent.

The display formatting changes correctly utilize the new formatAmount function for both the main amount display and the token amount display.

Also applies to: 373-373

}}
>
{utils.formatTokenAmount(parseFloat(amount), 2)} {tokenSymbol}
{utils.formatAmount(amount)} {tokenSymbol}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Hugo0 i tired to update the codebase to use the updated function in link preview component too, but unfortunately the fix didn't work as expected, it looks like a caching issue to me, i'm looking into this more deeply

Copy link
Contributor

Choose a reason for hiding this comment

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

@kushagrasarathe any update here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Hugo0 nothing sofar, tried changing the font size in a test commit, results are still same, can you try clearing the cache from vercel dashboard once?
Screenshot 2024-12-23 at 10 29 05 PM

* @returns formatted string representation of the number
*/
export const formatAmount = (amount: string | number): string => {
// handle undefined, null, or empty string
Copy link
Contributor

Choose a reason for hiding this comment

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

Issue, blocking: It'd be nice to test this function under various examples. Can we add test cases for it? Should be simple, we already have jest setup

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/utils/general.utils.ts (1)

242-250: ⚠️ Potential issue

Replace unsafe isNaN with Number.isNaN.

The current implementation uses the global isNaN which performs type coercion. This can lead to unexpected results.

Apply this fix:

-    if (isNaN(num)) return '0'
+    if (Number.isNaN(num)) return '0'
🧰 Tools
🪛 Biome (1.9.4)

[error] 250-250: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

🧹 Nitpick comments (1)
src/utils/general.utils.ts (1)

234-241: Add examples to the documentation.

While the documentation clearly explains the function's behavior, adding examples would make it even more helpful:

 /**
  * formats a number by:
  * - displaying 2 significant digits for small numbers (<0.01)
+ * Example: 0.00123 -> "0.0012"
  * - removing unnecessary trailing zeros after decimal point
+ * Example: 1.2300 -> "1.23"
  * - if all decimal places are zeros, returns the whole number
+ * Example: 1.000 -> "1"
  * @param amount - number or string to format
  * @returns formatted string representation of the number
  */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f6bcf13 and 850f4ae.

📒 Files selected for processing (1)
  • src/utils/general.utils.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/utils/general.utils.ts

[error] 250-250: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

🔇 Additional comments (1)
src/utils/general.utils.ts (1)

252-259: LGTM! Small numbers handling is well implemented.

The logic correctly handles small numbers by:

  1. Using exponential notation for precision control
  2. Converting back to decimal notation
  3. Maintaining 2 significant digits

Comment on lines +261 to +281
// for normal numbers, round to 2 decimals
const rounded = Number(num.toFixed(2))
const stringValue = rounded.toString()

// return as is if no decimal point
if (!stringValue.includes('.')) {
return stringValue
}

const [integerPart, decimalPart] = stringValue.split('.')

// return integer if decimal part is all zeros
if (!decimalPart || !/[1-9]/.test(decimalPart)) {
return integerPart
}

// remove trailing zeros from decimal part
const trimmedDecimal = decimalPart.replace(/0+$/, '')

// combine integer part with trimmed decimal
return `${integerPart}.${trimmedDecimal}`
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Now I have enough context to provide the final response.

Add unit tests for formatAmount function

The formatAmount function in src/utils/general.utils.ts currently lacks test coverage. Please add unit tests to verify:

  1. Small number handling (< 0.01)
    expect(formatAmount(0.001)).toBe('0.001')
  2. Normal number rounding
    expect(formatAmount(1.2345)).toBe('1.23')
  3. Trailing zeros removal
    expect(formatAmount(1.2300)).toBe('1.23')
    expect(formatAmount(1.0000)).toBe('1')
  4. Edge cases
    expect(formatAmount(undefined)).toBe('0')
    expect(formatAmount('')).toBe('0')
    expect(formatAmount('invalid')).toBe('0')
🔗 Analysis chain

Add unit tests to verify formatting behavior.

The implementation looks good, but it would benefit from comprehensive unit tests to verify:

  1. Rounding behavior for normal numbers
  2. Trailing zeros removal
  3. Whole numbers handling
  4. Edge cases

Would you like me to help generate unit tests for this function? Here's a sample test case to get started:

describe('formatAmount', () => {
  test('formats normal numbers correctly', () => {
    expect(formatAmount(1.2300)).toBe('1.23')
    expect(formatAmount(1.000)).toBe('1')
    expect(formatAmount(1.230)).toBe('1.23')
  })
})

Let me verify if there are existing tests for this functionality.


Let me try a different approach to find the function and related tests.


Let me check the existing test file to see if it contains tests for this functionality.


Let me find the complete function definition to determine its name.


Let me try one more search to find the function name and any existing tests for it.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Search for test files related to general.utils
fd "general.utils.*test" --type f

# Search for test cases related to formatAmount function
rg -l "formatAmount.*test|test.*formatAmount" 

# Look for the actual implementation to understand the function name and location
ast-grep --pattern 'function formatAmount($_) {
  $$$
}'

Length of output: 142


Script:

#!/bin/bash
# Find the actual function name from the implementation file
rg -A 5 "toFixed\(2\)" src/utils/general.utils.ts

# Search for any test files in the utils directory
fd "\.test\." src/utils/

# Search for test files containing number formatting tests
rg -l "test.*number.*format|format.*number.*test"

Length of output: 363


Script:

#!/bin/bash
# Check the content of the test file
cat src/utils/__tests__/format.utils.test.ts

# Also check the function name from the implementation file
rg -B 5 "toFixed\(2\)" src/utils/general.utils.ts

Length of output: 2960


Script:

#!/bin/bash
# Get more context around the number formatting function
rg -B 10 -A 15 "toFixed\(2\)" src/utils/general.utils.ts

Length of output: 935


Script:

#!/bin/bash
# Search for the function definition with more context
rg -B 15 -A 20 "Math\.abs\(num\) < 0\.01" src/utils/general.utils.ts

# Search for any test files that might contain number formatting tests
fd "general" --type f --exec grep -l "test" {}

Length of output: 1546

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/utils/__tests__/general.utils.test.ts (1)

1-73: Consider adding tests for extremes (e.g., Infinity, scientific notation).

Currently, the test suite does not cover extremely large numerical values or scientific notation inputs like '1e-8' or '1e8'. Similarly, Infinity and -Infinity inputs are untested. Adding these cases may help ensure robust handling of extreme float scenarios.

Would you like me to propose additional test cases covering Infinity, scientific notation, and other extreme values?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e88679f and 1ef36aa.

📒 Files selected for processing (1)
  • src/utils/__tests__/general.utils.test.ts (1 hunks)
🔇 Additional comments (6)
src/utils/__tests__/general.utils.test.ts (6)

1-1: Well-structured test imports.

The file correctly imports formatAmount from the relevant module. No issues here.


3-4: Good top-level description blocks.

The nested describe blocks for 'Amount Formatting Utilities' and 'formatAmount' establish a clear, organized structure for test categorization. This approach enhances readability and makes maintenance easier.


5-17: Comprehensive coverage of edge cases.

The tests for empty strings, invalid strings, and NaN correctly verify fallback behavior returning '0'. This is a robust approach for handling malformed or unexpected input.


19-35: Thorough testing of small number handling.

The suite checks various small magnitudes, both positive and negative, as well as string inputs, ensuring that the function correctly formats them to two significant digits. This set of tests is well-designed to catch precision issues.


37-54: Clear coverage for regular numbers.

These tests verify decimal rounding up to two places, the removal of trailing zeros, and correct handling of negative values. The coverage is broad and exemplifies good testing practices.


56-71: Excellent handling of whole numbers and zero.

By confirming that decimals are removed if they are all zeros, and that zero is displayed consistently as '0', these tests ensure that formatting aligns with user expectations for whole number representation.

@Hugo0 Hugo0 merged commit 2984520 into develop Dec 27, 2024
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 27, 2024
@Hugo0 Hugo0 deleted the fix/amount-formatting branch July 3, 2025 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants