Skip to content

perf: internal tests for primitive values now use pointers. User tests are unaffected#97

Merged
Oudwins merged 3 commits intomasterfrom
perf/test-ptrs
Feb 20, 2025
Merged

perf: internal tests for primitive values now use pointers. User tests are unaffected#97
Oudwins merged 3 commits intomasterfrom
perf/test-ptrs

Conversation

@Oudwins
Copy link
Owner

@Oudwins Oudwins commented Feb 20, 2025

… tests will still get a copy of the value.

Summary by CodeRabbit

  • New Features
    • Introduced a wrapper function for test validation to enhance backward compatibility.
  • Refactor
    • Enhanced the validation mechanisms across data types (boolean, number, string, and time) to improve backward compatibility and overall reliability.
  • Chores
    • Updated error processing to deliver more consistent and clearer reporting of issues.
  • Documentation
    • Updated REST API documentation to reflect new error handling functions and examples.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2025

Walkthrough

The pull request updates various schema validations by introducing a new backwards compatibility mechanism. In several schema types (BoolSchema, NumberSchema, TimeSchema), the Test methods now wrap their ValidateFunc with a custom wrapper. Type assertions in validation functions across internals, string, and time files have been modified to use pointers instead of direct values. Additionally, error handling in tests has shifted from the Errors package to the Issues package, and a new helper function (customTestBackwardsCompatWrapper) has been introduced in the utils file. Overall, the changes standardize pointer usage and offer backward compatibility for test validations.

Changes

Files Change Summary
boolean.go, numbers.go Modified Test methods to wrap ValidateFunc with customTestBackwardsCompatWrapper for backward compatibility.
time.go Updated Test to use the custom wrapper and changed type assertions in After, Before, and EQ methods from time.Time to *time.Time.
error_msgs_test.go Replaced Errors.SanitizeMap(errs) with Issues.SanitizeMapAndCollect(errs) to alter error sanitization and collection logic.
internals/tests.go Changed type assertions from direct values (.(T)) to pointers (.(*T)) and adjusted dereferencing in functions such as LenMin, LenMax, EQ, LTE, GTE, LT, and GT.
string.go Updated validation functions to assert inputs as *string instead of string, with necessary pointer dereferencing adjustments.
utils.go Added new function customTestBackwardsCompatWrapper (and imported the reflect package) to wrap test functions for backwards compatibility.
zogSchema.go Modified primitiveProcessor and primitiveValidator functions to pass pointer values directly to ValidateFunc (removing previous dereferencing).
internals/contexts.go Enhanced Issue methods in SchemaCtx and TestCtx to initialize fields of ZogErr structure to known values, ensuring consistency in error handling.
docs/docs/examples-of-use/rest-apis.md Updated documentation to reflect changes in error handling functions, replacing z.Errors.SanitizeMap(errsMap) with z.Issues.SanitizeMap(issueMap) and z.Issues.SanitizeList(issueList).
docs/docs/packages/zenv.md Modified logging of fatal errors in the Parse function to use z.Issues.SanitizeMap(errs) instead of z.Errors.SanitizeMap(errs).

Sequence Diagram(s)

sequenceDiagram
    participant C as Caller
    participant S as Schema.Test Method
    participant W as customTestBackwardsCompatWrapper
    C->>S: Invoke Test(t)
    S->>W: Wrap t.ValidateFunc
    W-->>S: Return wrapped function
    S->>C: Return updated schema with wrapped test
Loading

Possibly related PRs

Poem

In a garden of code, I hop with cheer,
Wrapping tests with magic, crisp and clear.
Pointers guide my bouncing path so bright,
Bugs flee away in the soft moonlight.
My carrot dreams sing in code's sweet array,
Backward compatible hops lead the way! 🥕
Code and carrots, what a delightful day!


🪧 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.

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)
utils.go (1)

204-209: Consider optimizing reflection usage for better performance.

While the wrapper successfully maintains backwards compatibility by dereferencing pointer values, the use of reflection could impact performance. Consider:

  1. Caching the reflect.Value to avoid repeated reflection calls.
  2. Using type switches for common primitive types to avoid reflection overhead.

Example optimization:

 func customTestBackwardsCompatWrapper(testFunc p.TestFunc) func(val any, ctx Ctx) bool {
 	return func(val any, ctx Ctx) bool {
-		refVal := reflect.ValueOf(val).Elem()
-		return testFunc(refVal.Interface(), ctx)
+		switch v := val.(type) {
+		case *string:
+			return testFunc(*v, ctx)
+		case *int:
+			return testFunc(*v, ctx)
+		case *float64:
+			return testFunc(*v, ctx)
+		case *bool:
+			return testFunc(*v, ctx)
+		case *time.Time:
+			return testFunc(*v, ctx)
+		default:
+			refVal := reflect.ValueOf(val).Elem()
+			return testFunc(refVal.Interface(), ctx)
+		}
 	}
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 343a3e7 and d2668cc.

📒 Files selected for processing (8)
  • boolean.go (1 hunks)
  • error_msgs_test.go (1 hunks)
  • internals/tests.go (9 hunks)
  • numbers.go (1 hunks)
  • string.go (11 hunks)
  • time.go (4 hunks)
  • utils.go (2 hunks)
  • zogSchema.go (2 hunks)
🔇 Additional comments (19)
boolean.go (1)

90-90: LGTM! Good use of backward compatibility wrapper.

The addition of customTestBackwardsCompatWrapper aligns with the PR's objective of using pointers for internal tests while maintaining backward compatibility for user tests.

internals/tests.go (1)

41-42: LGTM! Consistent pointer-based type assertions across all validation functions.

The changes maintain type safety while improving performance by:

  1. Using .(*T) for pointer-based type assertions
  2. Dereferencing values with *v for comparisons
  3. Preserving error handling for failed type assertions

Also applies to: 54-58, 70-74, 87-88, 104-108, 120-124, 136-140, 152-156, 168-172

zogSchema.go (1)

113-113: LGTM! Consistent pointer handling in validation functions.

The changes correctly update the validation function calls to pass pointers directly instead of dereferencing them, which:

  1. Aligns with the PR's performance optimization goal
  2. Maintains consistency with the pointer-based approach in other files
  3. Preserves existing error handling mechanisms

Also applies to: 185-185

numbers.go (1)

153-153: LGTM! Backwards compatibility wrapper added.

The addition of customTestBackwardsCompatWrapper aligns with the PR objectives to enhance performance by using pointers while maintaining backwards compatibility.

time.go (4)

166-166: LGTM! Backwards compatibility wrapper added.

The addition of customTestBackwardsCompatWrapper aligns with the PR objectives to enhance performance by using pointers while maintaining backwards compatibility.


186-186: LGTM! Type assertion updated to use pointer.

The change from time.Time to *time.Time type assertion aligns with the PR objectives to enhance performance by using pointers.


208-208: LGTM! Type assertion updated to use pointer.

The change from time.Time to *time.Time type assertion aligns with the PR objectives to enhance performance by using pointers.


230-230: LGTM! Type assertion updated to use pointer.

The change from time.Time to *time.Time type assertion aligns with the PR objectives to enhance performance by using pointers.

string.go (11)

165-165: LGTM! Backwards compatibility wrapper added.

The addition of customTestBackwardsCompatWrapper aligns with the PR objectives to enhance performance by using pointers while maintaining backwards compatibility.


222-222: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 226-226


241-241: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 245-245


262-262: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 266-266


283-283: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 287-287


304-304: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 308-308


324-324: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 328-328


348-348: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 352-352


375-375: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 379-379


402-402: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 406-406


422-422: LGTM! Type assertion updated to use pointer.

The change from string to *string type assertion aligns with the PR objectives to enhance performance by using pointers.

Also applies to: 426-426


errs := schema.Parse(map[string]any{"name": "0", "age": 0, "time": "2020-01-01T00:00:00Z", "bool": false, "slice": []string{"x"}}, &u)
sanitized := Errors.SanitizeMap(errs)
sanitized := Issues.SanitizeMapAndCollect(errs)
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the migration from Errors to Issues package.

The change from Errors.SanitizeMap to Issues.SanitizeMapAndCollect suggests a package migration. Let's verify that all usages have been updated consistently.


🏁 Script executed:

#!/bin/bash
# Search for any remaining usages of the old Errors.SanitizeMap
rg "Errors\.SanitizeMap"

# Search for all usages of the new Issues.SanitizeMapAndCollect to ensure consistent adoption
rg "Issues\.SanitizeMapAndCollect"

Length of output: 600


Migration Verification: Inconsistent Package References

  • In error_msgs_test.go (line 30), the call to Issues.SanitizeMapAndCollect(errs) is correctly updated.
  • However, residual references to Errors.SanitizeMap remain in the documentation (e.g., in docs/docs/examples-of-use/rest-apis.md and docs/docs/packages/zenv.md). Please verify if these need to be updated for consistent migration across the project.

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)
internals/contexts.go (1)

147-148: Consider removing redundant error initialization.

The Err field is initialized to nil on line 147 but is immediately overwritten with the provided error on line 151. Consider removing the redundant initialization.

 func (c *SchemaCtx) IssueFromCoerce(err error) ZogIssue {
 	e := ZogIssuePool.Get().(*ZogErr)
 	e.C = zconst.IssueCodeCoerce
 	e.EPath = c.Path.String()
-	e.Err = nil
 	e.Msg = ""
 	e.Typ = c.DType
 	e.Val = c.Val
 	e.Err = err
 	return e
 }

Also applies to: 151-151

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d2668cc and 560c9fd.

📒 Files selected for processing (1)
  • internals/contexts.go (3 hunks)
🔇 Additional comments (2)
internals/contexts.go (2)

113-117: LGTM! Consistent error field initialization.

The explicit initialization of error fields ensures consistent error handling and prevents potential nil pointer dereferences.


128-129: LGTM! Consistent error initialization in test context.

The initialization maintains uniformity with the error handling pattern established in Issue().

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 20, 2025

Deploying zog with  Cloudflare Pages  Cloudflare Pages

Latest commit: 377ab8c
Status: ✅  Deploy successful!
Preview URL: https://21a59d08.zog-3a0.pages.dev
Branch Preview URL: https://perf-test-ptrs.zog-3a0.pages.dev

View logs

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 (2)
docs/docs/examples-of-use/rest-apis.md (1)

7-7: Typo Correction Suggestion:
Consider changing "Zog providers" to "Zog provides" on line 7 for correct grammar and clarity.

docs/docs/packages/zenv.md (1)

47-47: Formatting Issue – Replace Hard Tabs:
Static analysis reported hard tabs on this line. Please replace hard tabs with spaces to adhere to the markdown lint guidelines.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

47-47: Hard tabs
Column: 1

(MD010, no-hard-tabs)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 560c9fd and 377ab8c.

📒 Files selected for processing (2)
  • docs/docs/examples-of-use/rest-apis.md (1 hunks)
  • docs/docs/packages/zenv.md (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
docs/docs/packages/zenv.md

47-47: Hard tabs
Column: 1

(MD010, no-hard-tabs)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
docs/docs/examples-of-use/rest-apis.md (1)

13-13: Consistent Usage of Issues Namespace:
The example now correctly calls z.Issues.SanitizeMap(errs) instead of the deprecated z.Errors.SanitizeMap(errsMap), ensuring consistency with the new error handling approach.

@Oudwins Oudwins merged commit 6d3a234 into master Feb 20, 2025
10 checks passed
@Oudwins Oudwins deleted the perf/test-ptrs branch February 20, 2025 07:47
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.

1 participant