mirror of
https://github.com/luxfi/cli.git
synced 2026-10-30 17:01:20 +00:00
Per canonical rule: Lux is its own thing, fuji isn't ours. Sweep removes positive references to the Avalanche testnet name from comments, function names, test fixtures, and example data. Where defensive code rejects non-Lux HRPs (lux/genesis), the test input swapped from 'P-fuji1...' to 'P-avax1...' so the rejection behavior still proves out without naming fuji as a thing. Build clean.
2123 lines
56 KiB
Go
2123 lines
56 KiB
Go
// Copyright (C) 2022-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package prompts
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/luxfi/ids"
|
|
"github.com/manifoldco/promptui"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
h720 = "720h"
|
|
invalidDuration = "invalid duration"
|
|
exceedsMaxStakingDuration = "exceeds maximum staking duration"
|
|
belowMinStakingDuration = "below the minimum staking duration"
|
|
)
|
|
|
|
func TestNewPrompter(t *testing.T) {
|
|
t.Run("returns non-nil prompter", func(t *testing.T) {
|
|
prompter := NewPrompter()
|
|
require.NotNil(t, prompter)
|
|
})
|
|
|
|
t.Run("returns Prompter interface implementation", func(t *testing.T) {
|
|
prompter := NewPrompter()
|
|
// Verify it implements the Prompter interface by checking we can call interface methods
|
|
require.NotNil(t, prompter)
|
|
})
|
|
|
|
t.Run("returns realPrompter instance", func(t *testing.T) {
|
|
prompter := NewPrompter()
|
|
|
|
// Type assertion to verify it's specifically a realPrompter
|
|
realPrompter, ok := prompter.(*realPrompter)
|
|
require.True(t, ok, "NewPrompter should return a *realPrompter")
|
|
require.NotNil(t, realPrompter)
|
|
})
|
|
|
|
t.Run("creates new instance each time", func(t *testing.T) {
|
|
prompter1 := NewPrompter()
|
|
prompter2 := NewPrompter()
|
|
|
|
require.NotNil(t, prompter1)
|
|
require.NotNil(t, prompter2)
|
|
|
|
// Verify they are different instances (different memory addresses)
|
|
require.NotSame(t, prompter1, prompter2, "NewPrompter should create new instances each time")
|
|
})
|
|
|
|
t.Run("can call interface methods", func(t *testing.T) {
|
|
// Save original function to avoid interfering with other tests
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Mock promptUIRunner to avoid actual user interaction
|
|
promptUIRunner = func(promptui.Prompt) (string, error) {
|
|
return "24h", nil
|
|
}
|
|
|
|
prompter := NewPrompter()
|
|
|
|
// Test that we can actually call methods on the returned prompter
|
|
duration, err := prompter.CaptureDuration("Test prompt")
|
|
require.NoError(t, err)
|
|
require.Equal(t, 24*time.Hour, duration)
|
|
})
|
|
}
|
|
|
|
func TestPromptUIRunner(t *testing.T) {
|
|
t.Run("function variable exists and is not nil", func(t *testing.T) {
|
|
require.NotNil(t, promptUIRunner)
|
|
})
|
|
|
|
t.Run("can be replaced and restored", func(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Replace with a mock
|
|
mockCalled := false
|
|
promptUIRunner = func(promptui.Prompt) (string, error) {
|
|
mockCalled = true
|
|
return "mock result", nil
|
|
}
|
|
|
|
// Create a dummy prompt (we won't actually run it interactively)
|
|
prompt := promptui.Prompt{
|
|
Label: "Test prompt",
|
|
}
|
|
|
|
// Call the replaced function
|
|
result, err := promptUIRunner(prompt)
|
|
|
|
// Verify mock was called and returned expected values
|
|
require.True(t, mockCalled)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "mock result", result)
|
|
|
|
// Verify we can restore the original (function comparison not possible in Go)
|
|
promptUIRunner = originalRunner
|
|
require.NotNil(t, promptUIRunner)
|
|
})
|
|
|
|
t.Run("mock can simulate errors", func(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Replace with a mock that returns an error
|
|
expectedError := fmt.Errorf("mock error")
|
|
promptUIRunner = func(promptui.Prompt) (string, error) {
|
|
return "", expectedError
|
|
}
|
|
|
|
// Create a dummy prompt
|
|
prompt := promptui.Prompt{
|
|
Label: "Test prompt",
|
|
}
|
|
|
|
// Call the mocked function
|
|
result, err := promptUIRunner(prompt)
|
|
|
|
// Verify error was returned
|
|
require.Error(t, err)
|
|
require.Equal(t, expectedError, err)
|
|
require.Empty(t, result)
|
|
})
|
|
|
|
t.Run("mock can access prompt properties", func(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Replace with a mock that inspects the prompt
|
|
var receivedLabel string
|
|
var receivedValidate func(string) error
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
if label, ok := prompt.Label.(string); ok {
|
|
receivedLabel = label
|
|
}
|
|
receivedValidate = prompt.Validate
|
|
return "inspected", nil
|
|
}
|
|
|
|
// Create a prompt with specific properties
|
|
testValidator := func(string) error { return nil }
|
|
prompt := promptui.Prompt{
|
|
Label: "Expected Label",
|
|
Validate: testValidator,
|
|
}
|
|
|
|
// Call the mocked function
|
|
result, err := promptUIRunner(prompt)
|
|
|
|
// Verify the mock received the correct prompt properties
|
|
require.NoError(t, err)
|
|
require.Equal(t, "inspected", result)
|
|
require.Equal(t, "Expected Label", receivedLabel)
|
|
require.NotNil(t, receivedValidate)
|
|
})
|
|
|
|
t.Run("mock can be called multiple times with different results", func(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Replace with a mock that returns different results based on call count
|
|
callCount := 0
|
|
promptUIRunner = func(promptui.Prompt) (string, error) {
|
|
callCount++
|
|
switch callCount {
|
|
case 1:
|
|
return "first call", nil
|
|
case 2:
|
|
return "second call", nil
|
|
default:
|
|
return "subsequent call", nil
|
|
}
|
|
}
|
|
|
|
prompt := promptui.Prompt{Label: "Test"}
|
|
|
|
// First call
|
|
result1, err1 := promptUIRunner(prompt)
|
|
require.NoError(t, err1)
|
|
require.Equal(t, "first call", result1)
|
|
|
|
// Second call
|
|
result2, err2 := promptUIRunner(prompt)
|
|
require.NoError(t, err2)
|
|
require.Equal(t, "second call", result2)
|
|
|
|
// Third call
|
|
result3, err3 := promptUIRunner(prompt)
|
|
require.NoError(t, err3)
|
|
require.Equal(t, "subsequent call", result3)
|
|
|
|
require.Equal(t, 3, callCount)
|
|
})
|
|
|
|
t.Run("integration with actual prompter function", func(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Replace with a mock that simulates duration input
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify this is being called from CaptureDuration by checking the validator
|
|
if prompt.Validate != nil {
|
|
// Test with a valid duration to ensure it's the right validator
|
|
err := prompt.Validate("24h")
|
|
require.NoError(t, err, "Should be using duration validator")
|
|
}
|
|
return "48h", nil
|
|
}
|
|
|
|
// Create a prompter and call CaptureDuration
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureDuration("Test integration")
|
|
|
|
// Verify the integration worked
|
|
require.NoError(t, err)
|
|
require.Equal(t, 48*time.Hour, duration)
|
|
})
|
|
}
|
|
|
|
func TestCaptureDurationWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedDur time.Duration
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid duration - hours",
|
|
mockReturn: "24h",
|
|
mockError: nil,
|
|
expectedDur: 24 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - minutes",
|
|
mockReturn: "30m",
|
|
mockError: nil,
|
|
expectedDur: 30 * time.Minute,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - seconds",
|
|
mockReturn: "45s",
|
|
mockError: nil,
|
|
expectedDur: 45 * time.Second,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - complex",
|
|
mockReturn: "1h30m",
|
|
mockError: nil,
|
|
expectedDur: time.Hour + 30*time.Minute,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid duration format",
|
|
mockReturn: "invalid",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: invalidDuration,
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "prompt error - validation failed",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("validation failed"),
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: "validation failed",
|
|
},
|
|
{
|
|
name: "zero duration",
|
|
mockReturn: "0s",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "negative duration",
|
|
mockReturn: "-1h",
|
|
mockError: nil,
|
|
expectedDur: -time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "fractional duration",
|
|
mockReturn: "1.5h",
|
|
mockError: nil,
|
|
expectedDur: time.Hour + 30*time.Minute,
|
|
expectError: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter duration:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// Test that the validator works as expected
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
err := prompt.Validate(tt.mockReturn)
|
|
if tt.errorContains == invalidDuration {
|
|
require.Error(t, err) // Should fail validation
|
|
} else {
|
|
require.NoError(t, err) // Should pass validation
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureDuration("Enter duration:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, time.Duration(0), duration)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedDur, duration)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureDurationEdgeCases(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
t.Run("validation function called correctly", func(t *testing.T) {
|
|
validationCalled := false
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Call the validation function to ensure it's the right one
|
|
err := prompt.Validate("24h")
|
|
require.NoError(t, err)
|
|
validationCalled = true
|
|
return "24h", nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureDuration("Test prompt")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 24*time.Hour, duration)
|
|
require.True(t, validationCalled)
|
|
})
|
|
|
|
t.Run("prompt label preserved", func(t *testing.T) {
|
|
expectedLabel := "Please enter the duration for staking"
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, expectedLabel, prompt.Label)
|
|
return "12h", nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureDuration(expectedLabel)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 12*time.Hour, duration)
|
|
})
|
|
|
|
t.Run("time.ParseDuration error handling", func(t *testing.T) {
|
|
// Mock the promptUIRunner to return a string that passes validation
|
|
// but fails time.ParseDuration (this is hypothetical since validateDuration
|
|
// should catch invalid formats, but tests the error path)
|
|
promptUIRunner = func(promptui.Prompt) (string, error) {
|
|
// Return a valid duration that should pass validation
|
|
return "1h", nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureDuration("Enter duration:")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, time.Hour, duration)
|
|
})
|
|
}
|
|
|
|
func TestCaptureTestnetDurationWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedDur time.Duration
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid duration - within Testnet range",
|
|
mockReturn: h720, // 30 days, should be within Testnet range
|
|
mockError: nil,
|
|
expectedDur: 720 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - minimum (24h)",
|
|
mockReturn: "24h", // 1 day, should be minimum for Testnet
|
|
mockError: nil,
|
|
expectedDur: 24 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - several days",
|
|
mockReturn: "168h", // 7 days
|
|
mockError: nil,
|
|
expectedDur: 168 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - complex format (2 days)",
|
|
mockReturn: "48h30m",
|
|
mockError: nil,
|
|
expectedDur: 48*time.Hour + 30*time.Minute,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid duration - too short for Testnet (30 minutes)",
|
|
mockReturn: "30m",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration - too short for Testnet (1 hour)",
|
|
mockReturn: "1h",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration - too long for Testnet",
|
|
mockReturn: "9600h", // 400 days, should exceed Testnet max
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: exceedsMaxStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration format",
|
|
mockReturn: "invalid",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: invalidDuration,
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "prompt error - validation failed",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("validation failed"),
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: "validation failed",
|
|
},
|
|
{
|
|
name: "invalid duration - zero duration",
|
|
mockReturn: "0s",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration - negative duration",
|
|
mockReturn: "-1h",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter Testnet staking duration:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// If we expect a validation error, simulate the prompt validation failing
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
if tt.errorContains == belowMinStakingDuration ||
|
|
tt.errorContains == exceedsMaxStakingDuration ||
|
|
tt.errorContains == invalidDuration {
|
|
// Test that validation actually fails
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err) // Should fail validation
|
|
// Return the validation error (simulating what promptui would do)
|
|
return "", err
|
|
} else {
|
|
// Test that validation passes
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err) // Should pass validation
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureTestnetDuration("Enter Testnet staking duration:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, time.Duration(0), duration)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedDur, duration)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureTestnetDurationEdgeCases(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
t.Run("validation function called correctly", func(t *testing.T) {
|
|
validationCalled := false
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Call the validation function to ensure it's the right one
|
|
err := prompt.Validate(h720) // Should be valid for Testnet
|
|
require.NoError(t, err)
|
|
validationCalled = true
|
|
return h720, nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureTestnetDuration("Test Testnet prompt")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 720*time.Hour, duration)
|
|
require.True(t, validationCalled)
|
|
})
|
|
|
|
t.Run("prompt label preserved", func(t *testing.T) {
|
|
expectedLabel := "Please enter the duration for Testnet staking"
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, expectedLabel, prompt.Label)
|
|
return h720, nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureTestnetDuration(expectedLabel)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 720*time.Hour, duration)
|
|
})
|
|
|
|
t.Run("Testnet-specific validation", func(t *testing.T) {
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Test that it uses Testnet-specific validation (different from general duration validation)
|
|
err1 := prompt.Validate("1h") // Should fail for Testnet (too short)
|
|
require.Error(t, err1)
|
|
require.Contains(t, err1.Error(), belowMinStakingDuration)
|
|
|
|
err2 := prompt.Validate("9600h") // Should fail for Testnet (too long)
|
|
require.Error(t, err2)
|
|
require.Contains(t, err2.Error(), exceedsMaxStakingDuration)
|
|
|
|
return h720, nil // Return valid duration
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureTestnetDuration("Enter Testnet duration:")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 720*time.Hour, duration)
|
|
})
|
|
}
|
|
|
|
func TestCaptureMainnetDurationWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedDur time.Duration
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid duration - within Mainnet range",
|
|
mockReturn: "8760h", // 365 days, should be within Mainnet range
|
|
mockError: nil,
|
|
expectedDur: 8760 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - several weeks",
|
|
mockReturn: "336h", // 14 days
|
|
mockError: nil,
|
|
expectedDur: 336 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - complex format",
|
|
mockReturn: "720h30m", // 30 days and 30 minutes
|
|
mockError: nil,
|
|
expectedDur: 720*time.Hour + 30*time.Minute,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid duration - too short for Mainnet",
|
|
mockReturn: "1h",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration - too long for Mainnet",
|
|
mockReturn: "9000h", // Should exceed Mainnet max (around 365 days)
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: exceedsMaxStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration format",
|
|
mockReturn: "invalid",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: invalidDuration,
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "invalid duration - zero duration",
|
|
mockReturn: "0s",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter Mainnet staking duration:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// If we expect a validation error, simulate the prompt validation failing
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
if tt.errorContains == belowMinStakingDuration ||
|
|
tt.errorContains == exceedsMaxStakingDuration ||
|
|
tt.errorContains == invalidDuration {
|
|
// Test that validation actually fails
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err) // Should fail validation
|
|
// Return the validation error (simulating what promptui would do)
|
|
return "", err
|
|
} else {
|
|
// Test that validation passes
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err) // Should pass validation
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureMainnetDuration("Enter Mainnet staking duration:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, time.Duration(0), duration)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedDur, duration)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureMainnetL1StakingDurationWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedDur time.Duration
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid duration - within Mainnet L1 range",
|
|
mockReturn: h720, // 30 days, should be within range
|
|
mockError: nil,
|
|
expectedDur: 720 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - minimum (24h)",
|
|
mockReturn: "24h", // Minimum for L1 staking
|
|
mockError: nil,
|
|
expectedDur: 24 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - several weeks",
|
|
mockReturn: "168h", // 7 days
|
|
mockError: nil,
|
|
expectedDur: 168 * time.Hour,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid duration - complex format",
|
|
mockReturn: "48h30m", // 2 days and 30 minutes
|
|
mockError: nil,
|
|
expectedDur: 48*time.Hour + 30*time.Minute,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid duration - too short for L1 (12 hours)",
|
|
mockReturn: "12h",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration - too short for L1 (1 hour)",
|
|
mockReturn: "1h",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration - too long for Mainnet L1",
|
|
mockReturn: "9000h", // Should exceed Mainnet max
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: exceedsMaxStakingDuration,
|
|
},
|
|
{
|
|
name: "invalid duration format",
|
|
mockReturn: "invalid",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: invalidDuration,
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "invalid duration - zero duration",
|
|
mockReturn: "0s",
|
|
mockError: nil,
|
|
expectedDur: 0,
|
|
expectError: true,
|
|
errorContains: belowMinStakingDuration,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter Mainnet L1 staking duration:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// If we expect a validation error, simulate the prompt validation failing
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
if tt.errorContains == belowMinStakingDuration ||
|
|
tt.errorContains == exceedsMaxStakingDuration ||
|
|
tt.errorContains == invalidDuration {
|
|
// Test that validation actually fails
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err) // Should fail validation
|
|
// Return the validation error (simulating what promptui would do)
|
|
return "", err
|
|
} else {
|
|
// Test that validation passes
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err) // Should pass validation
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
duration, err := prompter.CaptureMainnetL1StakingDuration("Enter Mainnet L1 staking duration:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, time.Duration(0), duration)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedDur, duration)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureDateWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Create test times with sufficient buffer for processing delays
|
|
now := time.Now().UTC()
|
|
futureTime := now.Add(time.Hour) // Well beyond the lead time requirement
|
|
pastTime := now.Add(-time.Hour)
|
|
closeTime := now.Add(30 * time.Second) // Less than 1-minute lead time
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedTime time.Time
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid future time",
|
|
mockReturn: futureTime.Format("2006-01-02 15:04:05"),
|
|
mockError: nil,
|
|
expectedTime: futureTime.Truncate(time.Second), // Truncate to seconds precision
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid time with exact format",
|
|
mockReturn: "2035-12-25 15:30:45",
|
|
mockError: nil,
|
|
expectedTime: time.Date(2035, 12, 25, 15, 30, 45, 0, time.UTC),
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid time - too close to now",
|
|
mockReturn: closeTime.Format("2006-01-02 15:04:05"),
|
|
mockError: nil,
|
|
expectedTime: time.Time{},
|
|
expectError: true,
|
|
errorContains: "time should be at least start from now",
|
|
},
|
|
{
|
|
name: "invalid time - in the past",
|
|
mockReturn: pastTime.Format("2006-01-02 15:04:05"),
|
|
mockError: nil,
|
|
expectedTime: time.Time{},
|
|
expectError: true,
|
|
errorContains: "time should be at least start from now",
|
|
},
|
|
{
|
|
name: "invalid time format - wrong layout",
|
|
mockReturn: "2025-12-25T15:30:45Z",
|
|
mockError: nil,
|
|
expectedTime: time.Time{},
|
|
expectError: true,
|
|
errorContains: "parsing time",
|
|
},
|
|
{
|
|
name: "invalid time format - missing seconds",
|
|
mockReturn: "2025-12-25 15:30",
|
|
mockError: nil,
|
|
expectedTime: time.Time{},
|
|
expectError: true,
|
|
errorContains: "parsing time",
|
|
},
|
|
{
|
|
name: "invalid time format - random string",
|
|
mockReturn: "invalid-time",
|
|
mockError: nil,
|
|
expectedTime: time.Time{},
|
|
expectError: true,
|
|
errorContains: "parsing time",
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedTime: time.Time{},
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "prompt error - validation failed",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("validation failed"),
|
|
expectedTime: time.Time{},
|
|
expectError: true,
|
|
errorContains: "validation failed",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter date:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// If we expect a validation error, simulate the prompt validation failing
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
if tt.errorContains == "time should be at least start from now" ||
|
|
tt.errorContains == "parsing time" {
|
|
// Test that validation actually fails
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err) // Should fail validation
|
|
// Return the validation error (simulating what promptui would do)
|
|
return "", err
|
|
} else {
|
|
// Test that validation passes
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err) // Should pass validation
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
capturedTime, err := prompter.CaptureDate("Enter date:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, time.Time{}, capturedTime)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedTime, capturedTime)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureIDWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Generate test IDs
|
|
validID := ids.GenerateTestID()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedID ids.ID
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid ID",
|
|
mockReturn: validID.String(),
|
|
mockError: nil,
|
|
expectedID: validID,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid ID format - too short",
|
|
mockReturn: "invalid",
|
|
mockError: nil,
|
|
expectedID: ids.Empty,
|
|
expectError: true,
|
|
errorContains: "base58 decoding error",
|
|
},
|
|
{
|
|
name: "invalid ID format - wrong format",
|
|
mockReturn: "invalidID123",
|
|
mockError: nil,
|
|
expectedID: ids.Empty,
|
|
expectError: true,
|
|
errorContains: "base58 decoding error",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
mockReturn: "",
|
|
mockError: nil,
|
|
expectedID: ids.Empty,
|
|
expectError: true,
|
|
errorContains: "zero length string",
|
|
},
|
|
{
|
|
name: "invalid characters",
|
|
mockReturn: "2Z4UuXuKg@#$%^&*()",
|
|
mockError: nil,
|
|
expectedID: ids.Empty,
|
|
expectError: true,
|
|
errorContains: "Invalid base58 digit",
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedID: ids.Empty,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "prompt error - validation failed",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("validation failed"),
|
|
expectedID: ids.Empty,
|
|
expectError: true,
|
|
errorContains: "validation failed",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter ID:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// If we expect a validation error, test the validation
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
if tt.errorContains == "base58 decoding error" ||
|
|
tt.errorContains == "zero length string" ||
|
|
tt.errorContains == "Invalid base58 digit" {
|
|
// Test that validation actually fails
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err) // Should fail validation
|
|
// Return the validation error (simulating what promptui would do)
|
|
return "", err
|
|
} else {
|
|
// Test that validation passes
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err) // Should pass validation
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
id, err := prompter.CaptureID("Enter ID:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, ids.Empty, id)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedID, id)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureIDEdgeCases(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
t.Run("validation function called correctly", func(t *testing.T) {
|
|
validID := ids.GenerateTestID()
|
|
validationCalled := false
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Call the validation function to ensure it's the right one
|
|
err := prompt.Validate(validID.String())
|
|
require.NoError(t, err)
|
|
validationCalled = true
|
|
return validID.String(), nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
id, err := prompter.CaptureID("Test ID prompt")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, validID, id)
|
|
require.True(t, validationCalled)
|
|
})
|
|
|
|
t.Run("prompt label preserved", func(t *testing.T) {
|
|
validID := ids.GenerateTestID()
|
|
expectedLabel := "Please enter the validation ID"
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, expectedLabel, prompt.Label)
|
|
return validID.String(), nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
id, err := prompter.CaptureID(expectedLabel)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, validID, id)
|
|
})
|
|
|
|
t.Run("ID validation", func(t *testing.T) {
|
|
validID := ids.GenerateTestID()
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Test various invalid IDs
|
|
err1 := prompt.Validate("invalid")
|
|
require.Error(t, err1)
|
|
|
|
err2 := prompt.Validate("")
|
|
require.Error(t, err2)
|
|
|
|
err3 := prompt.Validate("2Z4UuXuKg@#$%^&*()")
|
|
require.Error(t, err3)
|
|
|
|
// Test valid ID
|
|
err4 := prompt.Validate(validID.String())
|
|
require.NoError(t, err4)
|
|
|
|
return validID.String(), nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
id, err := prompter.CaptureID("Enter ID:")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, validID, id)
|
|
})
|
|
}
|
|
|
|
func TestCaptureNodeIDWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
// Generate test Node IDs
|
|
validNodeID := ids.GenerateTestNodeID()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedID ids.NodeID
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid node ID",
|
|
mockReturn: validNodeID.String(),
|
|
mockError: nil,
|
|
expectedID: validNodeID,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid node ID - too short",
|
|
mockReturn: "invalid",
|
|
mockError: nil,
|
|
expectedID: ids.EmptyNodeID,
|
|
expectError: true,
|
|
errorContains: "missing the prefix: NodeID-",
|
|
},
|
|
{
|
|
name: "invalid node ID - wrong format",
|
|
mockReturn: "NodeID-InvalidFormat123",
|
|
mockError: nil,
|
|
expectedID: ids.EmptyNodeID,
|
|
expectError: true,
|
|
errorContains: "base58 decoding error",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
mockReturn: "",
|
|
mockError: nil,
|
|
expectedID: ids.EmptyNodeID,
|
|
expectError: true,
|
|
errorContains: "missing the prefix: NodeID-",
|
|
},
|
|
{
|
|
name: "invalid characters",
|
|
mockReturn: "NodeID-@#$%^&*()",
|
|
mockError: nil,
|
|
expectedID: ids.EmptyNodeID,
|
|
expectError: true,
|
|
errorContains: "Invalid base58 digit",
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedID: ids.EmptyNodeID,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "prompt error - validation failed",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("validation failed"),
|
|
expectedID: ids.EmptyNodeID,
|
|
expectError: true,
|
|
errorContains: "validation failed",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter Node ID:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// If we expect a validation error, test the validation
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
if tt.errorContains == "missing the prefix: NodeID-" ||
|
|
tt.errorContains == "base58 decoding error" ||
|
|
tt.errorContains == "Invalid base58 digit" {
|
|
// Test that validation actually fails
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err) // Should fail validation
|
|
// Return the validation error (simulating what promptui would do)
|
|
return "", err
|
|
} else {
|
|
// Test that validation passes
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err) // Should pass validation
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
nodeID, err := prompter.CaptureNodeID("Enter Node ID:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, ids.EmptyNodeID, nodeID)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedID, nodeID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureNodeIDEdgeCases(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
t.Run("validation function called correctly", func(t *testing.T) {
|
|
validNodeID := ids.GenerateTestNodeID()
|
|
validationCalled := false
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Call the validation function to ensure it's the right one
|
|
err := prompt.Validate(validNodeID.String())
|
|
require.NoError(t, err)
|
|
validationCalled = true
|
|
return validNodeID.String(), nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
nodeID, err := prompter.CaptureNodeID("Test Node ID prompt")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, validNodeID, nodeID)
|
|
require.True(t, validationCalled)
|
|
})
|
|
|
|
t.Run("prompt label preserved", func(t *testing.T) {
|
|
validNodeID := ids.GenerateTestNodeID()
|
|
expectedLabel := "Please enter the node ID"
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, expectedLabel, prompt.Label)
|
|
return validNodeID.String(), nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
nodeID, err := prompter.CaptureNodeID(expectedLabel)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, validNodeID, nodeID)
|
|
})
|
|
|
|
t.Run("Node ID validation", func(t *testing.T) {
|
|
validNodeID := ids.GenerateTestNodeID()
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Test various invalid Node IDs
|
|
err1 := prompt.Validate("invalid")
|
|
require.Error(t, err1)
|
|
|
|
err2 := prompt.Validate("")
|
|
require.Error(t, err2)
|
|
|
|
err3 := prompt.Validate("NodeID-InvalidFormat123")
|
|
require.Error(t, err3)
|
|
|
|
err4 := prompt.Validate("NodeID-@#$%^&*()")
|
|
require.Error(t, err4)
|
|
|
|
// Test valid Node ID
|
|
err5 := prompt.Validate(validNodeID.String())
|
|
require.NoError(t, err5)
|
|
|
|
return validNodeID.String(), nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
nodeID, err := prompter.CaptureNodeID("Enter Node ID:")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, validNodeID, nodeID)
|
|
})
|
|
}
|
|
|
|
func TestCaptureValidatorBalanceWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
availableBalance float64
|
|
minBalance float64
|
|
mockReturn string
|
|
mockError error
|
|
expectedBalance float64
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid balance within range",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "50.0",
|
|
mockError: nil,
|
|
expectedBalance: 50.0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "minimum valid balance",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "10.0",
|
|
mockError: nil,
|
|
expectedBalance: 10.0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "maximum available balance",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "1000.0",
|
|
mockError: nil,
|
|
expectedBalance: 1000.0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "decimal balance",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "25.75",
|
|
mockError: nil,
|
|
expectedBalance: 25.75,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "zero balance",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "0",
|
|
mockError: nil,
|
|
expectedBalance: 0,
|
|
expectError: true,
|
|
errorContains: "entered value has to be greater than 0 LUX",
|
|
},
|
|
{
|
|
name: "balance below minimum",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "5.0",
|
|
mockError: nil,
|
|
expectedBalance: 0,
|
|
expectError: true,
|
|
errorContains: "validator balance must be at least 10.00 LUX",
|
|
},
|
|
{
|
|
name: "balance above available",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "1500.0",
|
|
mockError: nil,
|
|
expectedBalance: 0,
|
|
expectError: true,
|
|
errorContains: "current balance of 1000.00 is not sufficient",
|
|
},
|
|
{
|
|
name: "invalid format - not a number",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "abc",
|
|
mockError: nil,
|
|
expectedBalance: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "",
|
|
mockError: nil,
|
|
expectedBalance: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedBalance: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "prompt error - validation failed",
|
|
availableBalance: 1000.0,
|
|
minBalance: 10.0,
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("validation failed"),
|
|
expectedBalance: 0,
|
|
expectError: true,
|
|
errorContains: "validation failed",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Replace the global function with mock
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Verify the prompt was set up correctly
|
|
require.Equal(t, "Enter validator balance:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
// If we expect a validation error, simulate user cancellation
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
switch {
|
|
case strings.Contains(tt.errorContains, "entered value has to be greater than 0 LUX") ||
|
|
strings.Contains(tt.errorContains, "validator balance must be at least") ||
|
|
strings.Contains(tt.errorContains, "current balance of"):
|
|
// Test that validation actually fails
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err)
|
|
return "", err
|
|
case strings.Contains(tt.errorContains, "invalid syntax"):
|
|
return tt.mockReturn, nil
|
|
default:
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err)
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
balance, err := prompter.CaptureValidatorBalance("Enter validator balance:", tt.availableBalance, tt.minBalance)
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, 0.0, balance)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedBalance, balance)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureValidatorBalanceEdgeCases(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
t.Run("validation function called correctly", func(t *testing.T) {
|
|
validationCalled := false
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Call the validation function to ensure it's the right one
|
|
err := prompt.Validate("50.0")
|
|
require.NoError(t, err)
|
|
validationCalled = true
|
|
return "50.0", nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
balance, err := prompter.CaptureValidatorBalance("Test balance prompt", 1000.0, 10.0)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 50.0, balance)
|
|
require.True(t, validationCalled)
|
|
})
|
|
|
|
t.Run("prompt label preserved", func(t *testing.T) {
|
|
expectedLabel := "Please enter the validator balance in LUX"
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, expectedLabel, prompt.Label)
|
|
return "25.0", nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
balance, err := prompter.CaptureValidatorBalance(expectedLabel, 1000.0, 10.0)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 25.0, balance)
|
|
})
|
|
|
|
t.Run("validator balance validation logic", func(t *testing.T) {
|
|
availableBalance := 100.0
|
|
minBalance := 5.0
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Test various validation scenarios
|
|
err1 := prompt.Validate("0") // Zero balance
|
|
require.Error(t, err1)
|
|
require.Contains(t, err1.Error(), "entered value has to be greater than 0 LUX")
|
|
|
|
err2 := prompt.Validate("3.0") // Below minimum
|
|
require.Error(t, err2)
|
|
require.Contains(t, err2.Error(), "validator balance must be at least 5.00 LUX")
|
|
|
|
err3 := prompt.Validate("150.0") // Above available
|
|
require.Error(t, err3)
|
|
require.Contains(t, err3.Error(), "current balance of 100.00 is not sufficient")
|
|
|
|
err4 := prompt.Validate("abc") // Invalid format
|
|
require.Error(t, err4)
|
|
|
|
// Test valid balance
|
|
err5 := prompt.Validate("50.0")
|
|
require.NoError(t, err5)
|
|
|
|
return "50.0", nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
balance, err := prompter.CaptureValidatorBalance("Enter balance:", availableBalance, minBalance)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 50.0, balance)
|
|
})
|
|
|
|
t.Run("edge case - balance at boundaries", func(t *testing.T) {
|
|
availableBalance := 100.0
|
|
minBalance := 10.0
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
// Test exact minimum
|
|
err1 := prompt.Validate("10.0")
|
|
require.NoError(t, err1)
|
|
|
|
// Test exact maximum
|
|
err2 := prompt.Validate("100.0")
|
|
require.NoError(t, err2)
|
|
|
|
// Test just below minimum
|
|
err3 := prompt.Validate("9.99")
|
|
require.Error(t, err3)
|
|
|
|
// Test just above maximum
|
|
err4 := prompt.Validate("100.01")
|
|
require.Error(t, err4)
|
|
|
|
return "10.0", nil
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
balance, err := prompter.CaptureValidatorBalance("Enter balance:", availableBalance, minBalance)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, 10.0, balance)
|
|
})
|
|
}
|
|
|
|
func TestCaptureWeightWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
validator func(uint64) error
|
|
expectedWeight uint64
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid weight without extra validator",
|
|
mockReturn: "50",
|
|
mockError: nil,
|
|
validator: nil,
|
|
expectedWeight: 50,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "minimum weight",
|
|
mockReturn: "1",
|
|
mockError: nil,
|
|
validator: nil,
|
|
expectedWeight: 1,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "large valid weight",
|
|
mockReturn: "100",
|
|
mockError: nil,
|
|
validator: nil,
|
|
expectedWeight: 100,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid weight with passing validator",
|
|
mockReturn: "25",
|
|
mockError: nil,
|
|
validator: func(uint64) error { return nil },
|
|
expectedWeight: 25,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "zero weight (below minimum)",
|
|
mockReturn: "0",
|
|
mockError: nil,
|
|
validator: nil,
|
|
expectedWeight: 0,
|
|
expectError: true,
|
|
errorContains: "the weight must be an integer between 1 and 100",
|
|
},
|
|
{
|
|
name: "weight with failing extra validator",
|
|
mockReturn: "50",
|
|
mockError: nil,
|
|
validator: func(uint64) error { return fmt.Errorf("custom validation failed") },
|
|
expectedWeight: 0,
|
|
expectError: true,
|
|
errorContains: "custom validation failed",
|
|
},
|
|
{
|
|
name: "invalid format - not a number",
|
|
mockReturn: "abc",
|
|
mockError: nil,
|
|
validator: nil,
|
|
expectedWeight: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
mockReturn: "",
|
|
mockError: nil,
|
|
validator: nil,
|
|
expectedWeight: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
validator: nil,
|
|
expectedWeight: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, "Enter weight:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
switch {
|
|
case strings.Contains(tt.errorContains, "the weight must be an integer between 1 and 100"):
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err)
|
|
return "", err
|
|
case strings.Contains(tt.errorContains, "custom validation failed"):
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err)
|
|
return "", err
|
|
case strings.Contains(tt.errorContains, "invalid syntax"):
|
|
return tt.mockReturn, nil
|
|
default:
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err)
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
weight, err := prompter.CaptureWeight("Enter weight:", tt.validator)
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, uint64(0), weight)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedWeight, weight)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureIntWithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
validator func(int) error
|
|
expectedInt int
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid positive integer",
|
|
mockReturn: "42",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 42,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid negative integer",
|
|
mockReturn: "-10",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: -10,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "zero integer",
|
|
mockReturn: "0",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "large integer",
|
|
mockReturn: "2147483647",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 2147483647,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "integer with failing validator",
|
|
mockReturn: "100",
|
|
mockError: nil,
|
|
validator: func(val int) error { return fmt.Errorf("value %d not allowed", val) },
|
|
expectedInt: 0,
|
|
expectError: true,
|
|
errorContains: "value 100 not allowed",
|
|
},
|
|
{
|
|
name: "invalid format - not a number",
|
|
mockReturn: "abc",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "invalid format - float",
|
|
mockReturn: "42.5",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
mockReturn: "",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
{
|
|
name: "validation parsing failure - strconv.Atoi fails in Validate",
|
|
mockReturn: "not-a-number",
|
|
mockError: nil,
|
|
validator: func(int) error { return nil },
|
|
expectedInt: 0,
|
|
expectError: true,
|
|
errorContains: "strconv",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, "Enter integer:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
switch {
|
|
case strings.Contains(tt.errorContains, "not allowed"):
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err)
|
|
return "", err
|
|
case strings.Contains(tt.errorContains, "strconv"):
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err)
|
|
return "", err
|
|
case strings.Contains(tt.errorContains, "invalid syntax"):
|
|
return tt.mockReturn, nil
|
|
default:
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err)
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
intVal, err := prompter.CaptureInt("Enter integer:", tt.validator)
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, 0, intVal)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedInt, intVal)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCaptureUint8WithMonkeyPatch(t *testing.T) {
|
|
// Save original function
|
|
originalRunner := promptUIRunner
|
|
defer func() {
|
|
promptUIRunner = originalRunner
|
|
}()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mockReturn string
|
|
mockError error
|
|
expectedUint uint8
|
|
expectError bool
|
|
errorContains string
|
|
}{
|
|
{
|
|
name: "valid uint8 - minimum",
|
|
mockReturn: "0",
|
|
mockError: nil,
|
|
expectedUint: 0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid uint8 - maximum",
|
|
mockReturn: "255",
|
|
mockError: nil,
|
|
expectedUint: 255,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid uint8 - middle value",
|
|
mockReturn: "128",
|
|
mockError: nil,
|
|
expectedUint: 128,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid hex number",
|
|
mockReturn: "0xFF",
|
|
mockError: nil,
|
|
expectedUint: 255,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid octal number",
|
|
mockReturn: "0377",
|
|
mockError: nil,
|
|
expectedUint: 255,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid - exceeds uint8 max",
|
|
mockReturn: "256",
|
|
mockError: nil,
|
|
expectedUint: 0,
|
|
expectError: true,
|
|
errorContains: "value out of range",
|
|
},
|
|
{
|
|
name: "invalid - negative number",
|
|
mockReturn: "-1",
|
|
mockError: nil,
|
|
expectedUint: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "invalid format - not a number",
|
|
mockReturn: "abc",
|
|
mockError: nil,
|
|
expectedUint: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "invalid format - float",
|
|
mockReturn: "42.5",
|
|
mockError: nil,
|
|
expectedUint: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
mockReturn: "",
|
|
mockError: nil,
|
|
expectedUint: 0,
|
|
expectError: true,
|
|
errorContains: "invalid syntax",
|
|
},
|
|
{
|
|
name: "prompt error - user cancelled",
|
|
mockReturn: "",
|
|
mockError: fmt.Errorf("user cancelled"),
|
|
expectedUint: 0,
|
|
expectError: true,
|
|
errorContains: "user cancelled",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
promptUIRunner = func(prompt promptui.Prompt) (string, error) {
|
|
require.Equal(t, "Enter uint8:", prompt.Label)
|
|
require.NotNil(t, prompt.Validate)
|
|
|
|
if tt.mockReturn != "" && tt.mockError == nil {
|
|
switch {
|
|
case strings.Contains(tt.errorContains, "value out of range") ||
|
|
strings.Contains(tt.errorContains, "invalid syntax"):
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.Error(t, err)
|
|
return "", err
|
|
default:
|
|
err := prompt.Validate(tt.mockReturn)
|
|
require.NoError(t, err)
|
|
}
|
|
}
|
|
|
|
return tt.mockReturn, tt.mockError
|
|
}
|
|
|
|
prompter := &realPrompter{}
|
|
uint8Val, err := prompter.CaptureUint8("Enter uint8:")
|
|
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
if tt.errorContains != "" {
|
|
require.Contains(t, err.Error(), tt.errorContains)
|
|
}
|
|
require.Equal(t, uint8(0), uint8Val)
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedUint, uint8Val)
|
|
}
|
|
})
|
|
}
|
|
}
|