Skip to content

Commit babd157

Browse files
committed
fix: test cases
1 parent 2e72553 commit babd157

55 files changed

Lines changed: 20060 additions & 270 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,33 @@ jobs:
1515
- name: Set up Go
1616
uses: actions/setup-go@v5
1717
with:
18-
go-version: "1.23"
18+
go-version: "1.24"
1919

2020
- name: Build
2121
run: go build -v ./...
2222

23-
- name: Test
24-
run: go test -v ./...
23+
- name: Test with Coverage
24+
run: |
25+
mkdir -p .coverage
26+
go test -v -race -covermode=atomic -coverprofile=.coverage/coverage.out ./cmd/... ./internal/...
27+
28+
- name: Coverage Summary
29+
if: always()
30+
run: |
31+
if [ -f .coverage/coverage.out ]; then
32+
echo "### Test Coverage" >> $GITHUB_STEP_SUMMARY
33+
echo '```' >> $GITHUB_STEP_SUMMARY
34+
go tool cover -func=.coverage/coverage.out | grep -E '(total:|^github)' >> $GITHUB_STEP_SUMMARY
35+
echo '```' >> $GITHUB_STEP_SUMMARY
36+
fi
37+
38+
- name: Upload Coverage
39+
if: always()
40+
uses: actions/upload-artifact@v4
41+
with:
42+
name: coverage-report
43+
path: .coverage/coverage.out
44+
retention-days: 14
2545

2646
lint:
2747
runs-on: ubuntu-latest
@@ -31,7 +51,7 @@ jobs:
3151
- name: Set up Go
3252
uses: actions/setup-go@v5
3353
with:
34-
go-version: "1.23"
54+
go-version: "1.24"
3555

3656
- name: golangci-lint
3757
uses: golangci/golangci-lint-action@v7

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
scripts/build/pchaind
22
/push-validator
33
/push-validator.backup
4+
5+
# Coverage artifacts
6+
.coverage/
7+
coverage.out
8+
coverage.html

Makefile

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# push-validator-cli Makefile
2+
3+
COVERAGE_DIR := .coverage
4+
COVERAGE_PROFILE := $(COVERAGE_DIR)/coverage.out
5+
COVERAGE_HTML := $(COVERAGE_DIR)/coverage.html
6+
PACKAGES := ./cmd/... ./internal/...
7+
MIN_COVERAGE ?= 10
8+
9+
.PHONY: test coverage coverage-html coverage-check coverage-summary clean-coverage build lint help
10+
11+
## test: Run all tests with race detection
12+
test:
13+
go test -v -race $(PACKAGES)
14+
15+
## coverage: Run tests with coverage and show per-package breakdown
16+
coverage: clean-coverage
17+
@mkdir -p $(COVERAGE_DIR)
18+
go test -v -race -covermode=atomic -coverprofile=$(COVERAGE_PROFILE) $(PACKAGES)
19+
@echo ""
20+
@echo "=== Coverage Summary ==="
21+
@go tool cover -func=$(COVERAGE_PROFILE) | grep total:
22+
@echo ""
23+
@echo "=== Per-Package Coverage ==="
24+
@go tool cover -func=$(COVERAGE_PROFILE)
25+
@echo ""
26+
@echo "Coverage profile: $(COVERAGE_PROFILE)"
27+
28+
## coverage-html: Generate HTML coverage report and open it
29+
coverage-html: coverage
30+
go tool cover -html=$(COVERAGE_PROFILE) -o $(COVERAGE_HTML)
31+
@echo "HTML report: $(COVERAGE_HTML)"
32+
@command -v open >/dev/null 2>&1 && open $(COVERAGE_HTML) || true
33+
34+
## coverage-check: Verify coverage meets minimum threshold
35+
coverage-check: coverage
36+
@bash scripts/check-coverage.sh $(MIN_COVERAGE)
37+
38+
## coverage-summary: Print only the total coverage percentage
39+
coverage-summary:
40+
@mkdir -p $(COVERAGE_DIR)
41+
@go test -covermode=atomic -coverprofile=$(COVERAGE_PROFILE) $(PACKAGES) > /dev/null 2>&1
42+
@go tool cover -func=$(COVERAGE_PROFILE) | grep total: | awk '{print $$3}'
43+
44+
## clean-coverage: Remove coverage artifacts
45+
clean-coverage:
46+
@rm -rf $(COVERAGE_DIR)
47+
48+
## build: Build the push-validator binary
49+
build:
50+
go build -o push-validator ./cmd/push-validator/
51+
52+
## lint: Run golangci-lint
53+
lint:
54+
golangci-lint run ./...
55+
56+
## help: Show available targets
57+
help:
58+
@grep -E '^## ' Makefile | sed 's/## //' | column -t -s ':'

cmd/push-validator/cmd_chain.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Examples:
3939
push-validator chain install --force # Force reinstall`,
4040
RunE: func(cmd *cobra.Command, args []string) error {
4141
cfg := loadCfg()
42-
p := ui.NewPrinter(flagOutput)
42+
p := getPrinter()
4343

4444
installer := chain.NewInstaller(cfg.HomeDir)
4545

@@ -107,9 +107,9 @@ Examples:
107107
return fmt.Errorf("checksum verification failed: %w", err)
108108
}
109109
if verified {
110-
fmt.Printf(" %s Checksum verified\n", p.Colors.Success("✓"))
110+
fmt.Printf(" %s Checksum verified\n", p.Colors.Success(p.Colors.Emoji("✓")))
111111
} else {
112-
fmt.Printf(" %s Checksum file not available, skipping verification\n", p.Colors.Warning("⚠"))
112+
fmt.Printf(" %s Checksum file not available, skipping verification\n", p.Colors.Warning(p.Colors.Emoji("⚠")))
113113
}
114114
}
115115

@@ -130,9 +130,9 @@ Examples:
130130
}
131131

132132
if installedVer != "" {
133-
fmt.Printf(" %s Installed pchaind (%s)\n", p.Colors.Success("✓"), installedVer)
133+
fmt.Printf(" %s Installed pchaind (%s)\n", p.Colors.Success(p.Colors.Emoji("✓")), installedVer)
134134
} else {
135-
fmt.Printf(" %s Installed pchaind %s\n", p.Colors.Success("✓"), release.TagName)
135+
fmt.Printf(" %s Installed pchaind %s\n", p.Colors.Success(p.Colors.Emoji("✓")), release.TagName)
136136
}
137137

138138
return nil

cmd/push-validator/cmd_cosmovisor.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/spf13/cobra"
1010

1111
"github.com/pushchain/push-validator-cli/internal/cosmovisor"
12-
ui "github.com/pushchain/push-validator-cli/internal/ui"
1312
)
1413

1514
var cosmovisorCmd = &cobra.Command{
@@ -69,7 +68,7 @@ Example:
6968
func runCosmovisorStatus(cmd *cobra.Command, args []string) error {
7069
cfg := loadCfg()
7170
p := getPrinter()
72-
c := ui.NewColorConfigFromGlobal()
71+
c := getPrinter().Colors
7372

7473
detection := cosmovisor.Detect(cfg.HomeDir)
7574
svc := cosmovisor.New(cfg.HomeDir)
@@ -167,7 +166,7 @@ func runCosmovisorUpgradeInfo(cmd *cobra.Command, args []string) error {
167166
}
168167

169168
p := getPrinter()
170-
c := ui.NewColorConfigFromGlobal()
169+
c := getPrinter().Colors
171170

172171
ctx, cancel := context.WithTimeout(cmd.Context(), 2*time.Minute)
173172
defer cancel()

cmd/push-validator/cmd_doctor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func runDoctor(cmd *cobra.Command, args []string) error {
4545
cfg.HomeDir = flagHome
4646
}
4747

48-
c := ui.NewColorConfigFromGlobal()
48+
c := getPrinter().Colors
4949
results := []checkResult{}
5050

5151
// Header

cmd/push-validator/cmd_increase_stake.go

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
// handleIncreaseStake allows validators to increase their stake after registration
18-
func handleIncreaseStake(cfg config.Config) {
18+
func handleIncreaseStake(cfg config.Config) error {
1919
v := validator.NewWith(validator.Options{
2020
BinPath: findPchaind(),
2121
HomeDir: cfg.HomeDir,
@@ -35,27 +35,27 @@ func handleIncreaseStake(cfg config.Config) {
3535
getPrinter().JSON(map[string]any{"ok": false, "error": valErr.Error()})
3636
} else {
3737
fmt.Println()
38-
fmt.Println(getPrinter().Colors.Error("⚠️ Failed to retrieve validator information"))
38+
fmt.Println(getPrinter().Colors.Error(getPrinter().Colors.Emoji("⚠️") + " Failed to retrieve validator information"))
3939
fmt.Printf("Error: %v\n\n", valErr)
4040
fmt.Println(getPrinter().Colors.Info("Make sure you are registered as a validator first:"))
4141
fmt.Println(getPrinter().Colors.Apply(getPrinter().Colors.Theme.Command, " push-validator register-validator"))
4242
fmt.Println()
4343
}
44-
return
44+
return fmt.Errorf("failed to retrieve validator information: %w", valErr)
4545
}
4646

4747
if !myValInfo.IsValidator {
4848
if flagOutput == "json" {
4949
getPrinter().JSON(map[string]any{"ok": false, "error": "not a registered validator"})
5050
} else {
5151
fmt.Println()
52-
fmt.Println(getPrinter().Colors.Error("❌ This node is not registered as a validator"))
52+
fmt.Println(getPrinter().Colors.Error(getPrinter().Colors.Emoji("❌") + " This node is not registered as a validator"))
5353
fmt.Println()
5454
fmt.Println(getPrinter().Colors.Info("To register, use:"))
5555
fmt.Println(getPrinter().Colors.Apply(getPrinter().Colors.Theme.Command, " push-validator register-validator"))
5656
fmt.Println()
5757
}
58-
return
58+
return fmt.Errorf("not a registered validator")
5959
}
6060

6161
// Display current validator info
@@ -87,10 +87,10 @@ func handleIncreaseStake(cfg config.Config) {
8787
if flagOutput == "json" {
8888
getPrinter().JSON(map[string]any{"ok": false, "error": convErr.Error()})
8989
} else {
90-
fmt.Println(p.Colors.Error("⚠️ Failed to convert validator address"))
90+
fmt.Println(p.Colors.Error(p.Colors.Emoji("⚠️") + " Failed to convert validator address"))
9191
fmt.Printf("Error: %v\n\n", convErr)
9292
}
93-
return
93+
return fmt.Errorf("failed to convert validator address: %w", convErr)
9494
}
9595

9696
// Get account balance from Cosmos SDK
@@ -102,10 +102,10 @@ func handleIncreaseStake(cfg config.Config) {
102102
if flagOutput == "json" {
103103
getPrinter().JSON(map[string]any{"ok": false, "error": balErr.Error()})
104104
} else {
105-
fmt.Println(p.Colors.Error("⚠️ Failed to retrieve balance"))
105+
fmt.Println(p.Colors.Error(p.Colors.Emoji("⚠️") + " Failed to retrieve balance"))
106106
fmt.Printf("Error: %v\n\n", balErr)
107107
}
108-
return
108+
return fmt.Errorf("failed to retrieve balance: %w", balErr)
109109
}
110110

111111
// Display balance info
@@ -141,12 +141,12 @@ func handleIncreaseStake(cfg config.Config) {
141141
if flagOutput == "json" {
142142
getPrinter().JSON(map[string]any{"ok": false, "error": "insufficient balance"})
143143
} else {
144-
fmt.Println(p.Colors.Error("❌ Insufficient balance to delegate"))
144+
fmt.Println(p.Colors.Error(p.Colors.Emoji("❌") + " Insufficient balance to delegate"))
145145
fmt.Println()
146146
fmt.Println("You need at least 0.2 PC to increase stake (0.1 PC to delegate + 0.1 PC for fees).")
147147
fmt.Println()
148148
}
149-
return
149+
return fmt.Errorf("insufficient balance")
150150
}
151151

152152
// Prompt for delegation amount
@@ -161,32 +161,32 @@ func handleIncreaseStake(cfg config.Config) {
161161
input = strings.TrimSpace(input)
162162

163163
if input == "" {
164-
fmt.Println(p.Colors.Error("⚠ Amount is required. Try again."))
164+
fmt.Println(p.Colors.Error(p.Colors.Emoji("⚠") + " Amount is required. Try again."))
165165
continue
166166
}
167167

168168
// Parse user input
169169
delegateAmount, err := strconv.ParseFloat(input, 64)
170170
if err != nil {
171-
fmt.Println(p.Colors.Error("⚠ Invalid amount. Enter a number. Try again."))
171+
fmt.Println(p.Colors.Error(p.Colors.Emoji("⚠") + " Invalid amount. Enter a number. Try again."))
172172
continue
173173
}
174174

175175
// Validate bounds
176176
if delegateAmount < minDelegatePC {
177-
fmt.Printf(p.Colors.Error("⚠ Amount too low. Minimum delegation is %.1f PC. Try again.\n"), minDelegatePC)
177+
fmt.Printf(p.Colors.Error(p.Colors.Emoji("⚠") + " Amount too low. Minimum delegation is %.1f PC. Try again.\n"), minDelegatePC)
178178
continue
179179
}
180180
if delegateAmount > maxDelegatePCVal {
181-
fmt.Printf(p.Colors.Error("⚠ Insufficient balance. Maximum: %.1f PC. Try again.\n"), maxDelegatePCVal)
181+
fmt.Printf(p.Colors.Error(p.Colors.Emoji("⚠") + " Insufficient balance. Maximum: %.1f PC. Try again.\n"), maxDelegatePCVal)
182182
continue
183183
}
184184

185185
// Convert to wei
186186
delegateWei := new(big.Float).Mul(new(big.Float).SetFloat64(delegateAmount), new(big.Float).SetFloat64(1e18))
187187
delegationAmount = delegateWei.Text('f', 0)
188188

189-
fmt.Printf(p.Colors.Success("✓ Will delegate %.6f PC\n"), delegateAmount)
189+
fmt.Printf(p.Colors.Success(p.Colors.Emoji("✓") + " Will delegate %.6f PC\n"), delegateAmount)
190190
fmt.Println()
191191
break
192192
}
@@ -211,7 +211,7 @@ func handleIncreaseStake(cfg config.Config) {
211211
keyName = foundKey
212212
if flagOutput != "json" {
213213
fmt.Println()
214-
fmt.Printf("🔑 Using key: %s\n", keyName)
214+
fmt.Printf("%s Using key: %s\n", p.Colors.Emoji("🔑"), keyName)
215215
}
216216
} else {
217217
// Fall back to default if key not found
@@ -229,10 +229,10 @@ func handleIncreaseStake(cfg config.Config) {
229229
if flagOutput == "json" {
230230
getPrinter().JSON(map[string]any{"ok": false, "error": "could not determine key name"})
231231
} else {
232-
fmt.Println(p.Colors.Error("⚠️ Could not determine key name"))
232+
fmt.Println(p.Colors.Error(p.Colors.Emoji("⚠️") + " Could not determine key name"))
233233
fmt.Println()
234234
}
235-
return
235+
return fmt.Errorf("could not determine key name")
236236
}
237237

238238
// Execute delegation
@@ -252,10 +252,10 @@ func handleIncreaseStake(cfg config.Config) {
252252
getPrinter().JSON(map[string]any{"ok": false, "error": delegErr.Error()})
253253
} else {
254254
fmt.Println()
255-
fmt.Println(p.Colors.Error("❌ Delegation failed"))
255+
fmt.Println(p.Colors.Error(p.Colors.Emoji("❌") + " Delegation failed"))
256256
fmt.Printf("Error: %v\n\n", delegErr)
257257
}
258-
return
258+
return fmt.Errorf("delegation transaction failed: %w", delegErr)
259259
}
260260

261261
// Success output
@@ -267,7 +267,7 @@ func handleIncreaseStake(cfg config.Config) {
267267
})
268268
} else {
269269
fmt.Println()
270-
p.Success("✅ Delegation successful!")
270+
p.Success(p.Colors.Emoji("✅") + " Delegation successful!")
271271
fmt.Println()
272272

273273
// Display delegation details
@@ -291,4 +291,5 @@ func handleIncreaseStake(cfg config.Config) {
291291
fmt.Println(p.Colors.Apply(p.Colors.Theme.Command, " push-validator dashboard"))
292292
fmt.Println()
293293
}
294+
return nil
294295
}

0 commit comments

Comments
 (0)