Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor formatValue #202

Merged
merged 13 commits into from
Dec 29, 2022
Merged

Conversation

rafiramadhana
Copy link
Contributor

@rafiramadhana rafiramadhana commented Dec 18, 2022

Issue: (part of) #190

Refactoring before proceeding to introduce DefaultFormatter.DisableScientific as mentioned in #190 (comment).

Refactoring (more detail #190 (comment)):

  • Delete formatFloat. Replace with formatValue
  • Rework formatTyped to use formatValue
  • Rework formatRange to use formatValue
  • Introduce scientific as default float format

Tasks:

  • Add unit test to catch potential breaking early
  • Refactor
  • Re-evaluate unit test

PR will be draft, unless all tasks are checked

PR is now ready

Add unit test to cover formatFloat, formatRange, and formatTyped.
@rafiramadhana
Copy link
Contributor Author

hi @gavv , I've added unit test to guard from potential breaking when refactoring the formatValue

would you mind to take a look? thanks

@coveralls
Copy link
Collaborator

coveralls commented Dec 18, 2022

Coverage Status

Coverage: 95.302% (+0.03%) from 95.275% when pulling ab04aae on neverbeenthisweeb:190-enable-scientific-formatter into 08a8b63 on gavv:master.

@gavv
Copy link
Owner

gavv commented Dec 19, 2022

Nice!

Tests look good, but I thought you were going to create tests based on FormatData instead of of format template?

My understanding of the discussion was that template-based tests will be e2e tests covered by #165.

formatter_test.go Outdated Show resolved Hide resolved
@rafiramadhana
Copy link
Contributor Author

Nice!

Tests look good, but I thought you were going to create tests based on FormatData instead of of format template?

My understanding of the discussion was that template-based tests will be e2e tests covered by #165.

i see, sry

i thought it would be:

  • e2e: format template
  • unit test: FormatData + format template

ok, will adjust accordingly, so that:

  • e2e: format template
  • unit test: FormatData

Update unit test to assert buildFormatData.
@rafiramadhana
Copy link
Contributor Author

rafiramadhana commented Dec 19, 2022

updated

  • Remove underscore in test names
  • Test buildFormatData instead of template string

@rafiramadhana
Copy link
Contributor Author

@gavv hi, may i know what is the intention of isNumber?

i think it is a bit vague when we see the existing formatFloat:

func formatFloat(value interface{}) string {
	switch value.(type) {
	case float32, float64:
		return fmt.Sprintf("%f", value)
	}

	if isNumber(value) {
		return fmt.Sprintf("%v", value)
	}

	return formatValue(value)
}

float32 and float64 are also numbers right? why we differ them from isNumber's check?

@rafiramadhana
Copy link
Contributor Author

rafiramadhana commented Dec 19, 2022

@gavv and maybe about formatValue

is it safe for me to assume in formatValue:

func formatValue(value interface{}) string {

that this part

if s, _ := value.(fmt.Stringer); s != nil {
	if ss := s.String(); strings.TrimSpace(ss) != "" {
		return ss
	}
}

has the same intention as formatString?

func formatString(value interface{}) string {

@gavv
Copy link
Owner

gavv commented Dec 19, 2022

@gavv hi, may i know what is the intention of isNumber?

Intention was to use %f for floats and %v for other numbers (i.e. integers).

@gavv
Copy link
Owner

gavv commented Dec 19, 2022

is it safe for me to assume in formatValue:
has the same intention as formatString?

IIRC they're different.

formatString is for printing bare strings. If value is string, it is printed as is, without adding quotes or anything. If it's not string, there is a fallback that uses formatValue. Other methods, e.g. formatRange, formatList, have similar fallbacks. Maybe it makes sense to rename them to formatStringOrValue, formatRangeOrValue, formatListOrValue.

formatValue is for printer arbitrary objects. It prints most values as JSON, with a few exceptions. If value is http.*, it prints it using litter. If value implements Stringer interface, i.e. it's an object with String() method, it uses that method to format object. It allows to pass values with custom formatting representation, e.g. see wsMessageType and wsCloseCode.

@gavv
Copy link
Owner

gavv commented Dec 19, 2022

Note that when you pass a string to formatValue, it will select json.Marshal branch and print the string with quotes (this is how JSON represents strings). And if you pass string to formatString, it will print it without quotes.

Maybe it makes sens to rename formatString to formatBareString (or formatBareStringOrValue) to make this detail clearer.

@gavv
Copy link
Owner

gavv commented Dec 19, 2022

We could also rename formatTyped to formatValueWithType.

@rafiramadhana
Copy link
Contributor Author

@gavv ok thanks for the feedbacks

will revisit this pr either this weekend/next week

sry for late responses

@gavv
Copy link
Owner

gavv commented Dec 23, 2022

Great, thanks!

In addition, we also rename formatString to formatBareString.
Refactor formatValue to handle number types (e.g. int, float32, and float64).

Deprecate formatFloat.

Refactor formatRange and formatTyped to use formatValue for number types.
@rafiramadhana
Copy link
Contributor Author

rafiramadhana commented Dec 25, 2022

@gavv Hi, this MR is now ready for review.

Maybe it makes sense to rename them to formatStringOrValue, formatRangeOrValue, formatListOrValue.

However, I haven't done those renaming changes. I think the OrValue is a bit vague about what meaning that it conveys. In addition, it is more readable without the OrValue IMO.

We could also rename formatTyped to formatValueWithType.

I also haven't done this change because I think it shows that formatTyped (which later renamed to formatValueWithType) has the same logic with formatValue.

I think, they are different because formatTyped uses %#v, while formatValue uses %v. Wdyt?

At the end, discussion is very welcome. We can do the changes here, or it could also be in another MR.

@rafiramadhana rafiramadhana marked this pull request as ready for review December 25, 2022 16:26
@rafiramadhana
Copy link
Contributor Author

rafiramadhana commented Dec 25, 2022

Btw, the e2e test will be done in another MR, can also have different issue for that.

I think, we can focus on the unit tests first + impl of .DisableScientific.

@gavv
Copy link
Owner

gavv commented Dec 26, 2022

I think the OrValue is a bit vague about what meaning that it conveys. In addition, it is more readable without the OrValue IMO.

I also haven't done this change because I think it shows that formatTyped (which later renamed to formatValueWithType) has the same logic with formatValue.

Makes sense. Let's keep it as is, then.

I think, we can focus on the unit tests first + impl of .DisableScientific.

Agree.

Copy link
Owner

@gavv gavv left a comment

Choose a reason for hiding this comment

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

Thanks for update! A few more comments.

formatter_test.go Outdated Show resolved Hide resolved
formatter_test.go Show resolved Hide resolved
Refactor TestFormatDataFailureActual to use table driven approach.
Update unit test to use table driven approach.
@rafiramadhana
Copy link
Contributor Author

@gavv ready for review

@gavv gavv added the ready for review Pull request can be reviewed label Dec 28, 2022
@gavv gavv merged commit 0ca7d22 into gavv:master Dec 29, 2022
@gavv
Copy link
Owner

gavv commented Dec 29, 2022

Awesome, thanks!

@gavv gavv removed the ready for review Pull request can be reviewed label Dec 29, 2022
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.

3 participants