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

Change testJSONMarshal #2708

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Conversation

exageraldo
Copy link
Contributor

Fixes: #2699

@codecov
Copy link

codecov bot commented Mar 15, 2023

Codecov Report

Merging #2708 (d29f932) into master (77b5b3d) will increase coverage by 0.03%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master    #2708      +/-   ##
==========================================
+ Coverage   98.13%   98.16%   +0.03%     
==========================================
  Files         148      148              
  Lines       12783    12783              
==========================================
+ Hits        12544    12548       +4     
+ Misses        164      160       -4     
  Partials       75       75              
Files Coverage Δ
github/orgs_audit_log.go 100.00% <ø> (ø)
github/search.go 93.61% <ø> (ø)
github/teams.go 98.18% <ø> (ø)
github/teams_members.go 95.23% <ø> (ø)
github/users.go 94.17% <ø> (ø)

... and 1 file with indirect coverage changes

@gmlewis
Copy link
Collaborator

gmlewis commented Mar 16, 2023

Thanks, @exageraldo ! Please remove "Draft" status when you would like me to review this PR.

github/github.go Outdated Show resolved Hide resolved
…ces before comparison (inside testJSONMarshal)
…itError_Marshal and TestAbuseRateLimitError_Marshal
@exageraldo
Copy link
Contributor Author

Some tests are no longer _Marshal but _addOtions, because the structures are responsible for mounting query strings, not a json.

TestGetAuditLogOptions_addOptions
TestTrafficBreakdownOptions_addOptions
TestSearchOptions_addOptions
TestTeamListTeamMembersOptions_addOptions
TestListExternalGroupsOptions_addOptions
TestUserListOptions_addOptions
TestHovercardOptions_addOptions

Since we do a tag validation in the testAddURLOptions function, I had to make some small changes to the following structures for the tests to pass.

GetAuditLogOptions ~> ListCursorOptions `url:",omitempty"`
SearchOptions ~> ListOptions `url:",omitempty"`
TeamListTeamMembersOptions ~> ListOptions `url:",omitempty"`
ListExternalGroupsOptions ~> ListOptions `url:",omitempty"`
UserListOptions ~> ListOptions `url:",omitempty"`

Theoretically it is just an explicit way of leaving the structure as it already was (did that make any sense?)

@exageraldo
Copy link
Contributor Author

exageraldo commented Mar 22, 2023

In some cases, I had to use json.Marshal to mount part of the expected string.

github/event_types_test.go

part, _ := json.Marshal(">= 2.0.0, < 2.0.2")

github/teams_discussions_test.go

bodyHTML, _ := json.Marshal(`<p>test</p>`)

In both cases, the idea is just to convert ">" into "\u003e" and "<" into "\u003c".

Do you think we can keep it that way, or can we add two other strings.Replace inside the testJSONMarshal function?

want = strings.Replace(want, ">", "\u003e", -1)
want = strings.Replace(want, "<", "\u003c", -1)

I could not find any other simple way to handle this.


And now a new case:

github/repos_contents_test.go

contentValue, _ := json.Marshal([]byte{1})

@gmlewis
Copy link
Collaborator

gmlewis commented Mar 23, 2023

Yeah, those cases look a bit odd.
Go ahead with what you think is best, and then when I take the time to review the whole PR, I might come up with other ideas. 😄

@exageraldo exageraldo changed the title [WIP] Change testJSONMarshal Change testJSONMarshal Mar 24, 2023
@exageraldo exageraldo marked this pull request as ready for review March 24, 2023 00:22
@gmlewis
Copy link
Collaborator

gmlewis commented Sep 18, 2023

We'll give this PR a couple weeks to get a reply and have the conflicts resolved, then if we haven't got any updates, it will be closed as abandoned.

@exageraldo
Copy link
Contributor Author

I'll fix these things by this weekend 😄

@gmlewis
Copy link
Collaborator

gmlewis commented Sep 18, 2023

Awesome - @exageraldo - thank you for the update!
No rush, actually - I just need to clean out old, abandoned PRs periodically.

@exageraldo
Copy link
Contributor Author

hey, sorry for the delay. i had some unforeseen circumstances here, but I'm already finalizing it! by monday I'll be pushing up the changes.

@gmlewis
Copy link
Collaborator

gmlewis commented Oct 10, 2023

Why are you changing GitHub workflows?

@exageraldo
Copy link
Contributor Author

I didn't change anything in the workflows. I ended up opting for a "merge" instead of a "rebase" because some changes were disappearing and I didn't know how to solve it. If you look in the "Files Changed" tab, you'll see that all the changes are related to tests only.

@gmlewis
Copy link
Collaborator

gmlewis commented Oct 10, 2023

I'll look again when I'm not on my android phone later today.

@gmlewis
Copy link
Collaborator

gmlewis commented Oct 10, 2023

OK, I must have been looking only at a merge commit... looking now and it is looking much better, thanks.
Performing code review...

Copy link
Collaborator

@gmlewis gmlewis left a comment

Choose a reason for hiding this comment

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

Wow, thank you, @exageraldo !
A have a few questions...

}

if diff := cmp.Diff(string(w), string(got)); diff != "" {
t.Errorf("json.Marshal returned:\n%s\nwant:\n%s\ndiff:\n%v", got, w, diff)
// Remove all spaces and new lines from the JSON strings.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// Remove all spaces and new lines from the JSON strings.
// Remove all tabs and newlines from the JSON strings.

want = strings.Replace(want, "\t", "", -1)
want = strings.Replace(want, "\n", "", -1)

// Replace the "<" and ">" characters with their unicode escape sequences.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems odd - why was this necessary?

Comment on lines -2715 to 2751
func TestRateLimitError_Marshal(t *testing.T) {
testJSONMarshal(t, &RateLimitError{}, "{}")

u := &RateLimitError{
Rate: Rate{
Limit: 1,
Remaining: 1,
Reset: Timestamp{referenceTime},
},
Message: "msg",
}

want := `{
"Rate": {
"limit": 1,
"remaining": 1,
"reset": ` + referenceTimeStr + `
},
"message": "msg"
}`

testJSONMarshal(t, u, want)
}

func TestAbuseRateLimitError_Marshal(t *testing.T) {
testJSONMarshal(t, &AbuseRateLimitError{}, "{}")

u := &AbuseRateLimitError{
Message: "msg",
}

want := `{
"message": "msg"
"reason":"reason",
"created_at":` + referenceTimeStr + `
}`

testJSONMarshal(t, u, want)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why were these removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

wow. It wasn't supposed to happen.
I think it was when I sync the branch. I'll add it again!

@@ -16,7 +16,7 @@ type GetAuditLogOptions struct {
Include *string `url:"include,omitempty"` // Event type includes. Can be one of "web", "git", "all". Default: "web". (Optional.)
Order *string `url:"order,omitempty"` // The order of audit log events. Can be one of "asc" or "desc". Default: "desc". (Optional.)

ListCursorOptions
ListCursorOptions `url:",omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems odd - why is this necessary for an embedded struct?

@@ -54,7 +54,7 @@ type SearchOptions struct {
// Whether to retrieve text match metadata with a query
TextMatch bool `url:"-"`

ListOptions
ListOptions `url:",omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

This also seems odd - why is this needed?

@@ -17,7 +17,7 @@ type TeamListTeamMembersOptions struct {
// values are "all", "member", "maintainer". Default is "all".
Role string `url:"role,omitempty"`

ListOptions
ListOptions `url:",omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same thing

@@ -196,7 +196,7 @@ type UserListOptions struct {
// Note: Pagination is powered exclusively by the Since parameter,
// ListOptions.Page has no effect.
// ListOptions.PerPage controls an undocumented GitHub API parameter.
ListOptions
ListOptions `url:",omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto

@WillAbides
Copy link
Contributor

WillAbides commented Oct 11, 2023

We could simplify this by changing testJSONMarshal to this:

// Test whether the marshaling of v produces JSON that corresponds
// to the want string.
func testJSONMarshal(t *testing.T, v interface{}, want string) {
	t.Helper()
	got, err := json.Marshal(v)
	if err != nil {
		t.Errorf("Unable to marshal JSON for %#v", v)
	}
	got = normalizeJSON(t, got)
	wantBytes := normalizeJSON(t, []byte(want))
	diff := cmp.Diff(string(wantBytes), string(got))
	if diff != "" {
		t.Errorf("json.Marshal returned:\n%s\nwant:\n%s\ndiff:\n%v", string(got), string(wantBytes), diff)
	}
}

// normalizeJSON normalizes the JSON in b by unmarshaling and marshaling it
// again.
func normalizeJSON(t *testing.T, b []byte) []byte {
	t.Helper()
	var v interface{}
	err := json.Unmarshal(b, &v)
	if err != nil {
		t.Errorf("Unable to unmarshal JSON for %v: %v", string(b), err)
	}
	w, err := json.MarshalIndent(v, "", "  ")
	if err != nil {
		t.Errorf("Unable to marshal JSON for %#v", v)
	}
	return w
}

That way differences like casing are failures but it isn't required to have the same whitespace or order of fields. This is similar to what testify does with assert.JSONEq().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

about testJSONMarshal's behavior
3 participants