diff --git a/CHANGELOG.md b/CHANGELOG.md index 2107842..803925f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.2.1 - 2026-01-23 + +- CLI: accept long flags with `--flag=value` (same behavior as space-separated). +- Docs: note `--flag=value` support for long flags. + ## 0.2.0 - 2026-01-02 - Autocomplete suggestions for places and queries (client + CLI). diff --git a/README.md b/README.md index a2da0a1..c2ebf40 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Modern Go client + CLI for the Google Places API (New). Fast for humans, tidy fo ## Install / Run +Latest release: v0.2.1 (2026-01-23). + - Homebrew: `brew install steipete/tap/goplaces` - Go: `go install github.com/steipete/goplaces/cmd/goplaces@latest` - Source: `make goplaces` @@ -70,6 +72,8 @@ Optional overrides: ## CLI +Long flags accept `--flag value` or `--flag=value` (examples use space). + ```text goplaces [--api-key=KEY] [--base-url=URL] [--routes-base-url=URL] [--timeout=10s] [--json] [--no-color] [--verbose] diff --git a/internal/cli/cli_equals_test.go b/internal/cli/cli_equals_test.go new file mode 100644 index 0000000..deb0c7c --- /dev/null +++ b/internal/cli/cli_equals_test.go @@ -0,0 +1,117 @@ +package cli + +import ( + "bytes" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestRunSearchWithEqualsFlags(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte(`{"places": [{"id": "abc"}]}`)) + })) + defer server.Close() + + var stdout bytes.Buffer + var stderr bytes.Buffer + + exitCode := Run([]string{ + "search", + "coffee", + "--api-key=test-key", + "--base-url=" + server.URL, + "--json", + "--min-rating=4.2", + "--limit=5", + }, &stdout, &stderr) + + if exitCode != 0 { + t.Fatalf("expected exit code 0, got %d (stdout=%s stderr=%s)", exitCode, stdout.String(), stderr.String()) + } + if stderr.Len() != 0 { + t.Fatalf("unexpected stderr: %s", stderr.String()) + } + if !strings.HasPrefix(strings.TrimSpace(stdout.String()), "[") { + t.Fatalf("expected JSON array output, got: %s", stdout.String()) + } +} + +func TestRunNearbyWithEqualsFlags(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/places:searchNearby" { + t.Fatalf("unexpected path: %s", r.URL.Path) + } + _, _ = w.Write([]byte(`{"places": [{"id": "abc"}]}`)) + })) + defer server.Close() + + var stdout bytes.Buffer + var stderr bytes.Buffer + + exitCode := Run([]string{ + "nearby", + "--lat=1", + "--lng=2", + "--radius-m=3", + "--type=cafe", + "--exclude-type=bar", + "--limit=5", + "--api-key=test-key", + "--base-url=" + server.URL, + "--json", + }, &stdout, &stderr) + + if exitCode != 0 { + t.Fatalf("expected exit code 0, got %d (stdout=%s stderr=%s)", exitCode, stdout.String(), stderr.String()) + } + if stderr.Len() != 0 { + t.Fatalf("unexpected stderr: %s", stderr.String()) + } + if !strings.HasPrefix(strings.TrimSpace(stdout.String()), "[") { + t.Fatalf("expected JSON array output, got: %s", stdout.String()) + } +} + +func TestRunRouteWithEqualsFlags(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/directions/v2:computeRoutes": + _, _ = w.Write([]byte("{\"routes\":[{\"polyline\":{\"encodedPolyline\":\"_p~iF~ps|U_ulLnnqC_mqNvxq`@\"}}]}")) + case placesSearchPath: + _, _ = w.Write([]byte(`{"places":[{"id":"abc","displayName":{"text":"Cafe"}}]}`)) + default: + t.Fatalf("unexpected path: %s", r.URL.Path) + } + })) + defer server.Close() + + var stdout bytes.Buffer + var stderr bytes.Buffer + + exitCode := Run([]string{ + "route", + "coffee", + "--from=A", + "--to=B", + "--api-key=test-key", + "--base-url=" + server.URL, + "--routes-base-url=" + server.URL, + "--mode=WALK", + "--radius-m=1200", + "--max-waypoints=3", + "--limit=2", + "--json", + }, &stdout, &stderr) + + if exitCode != 0 { + t.Fatalf("expected exit code 0, got %d (stdout=%s stderr=%s)", exitCode, stdout.String(), stderr.String()) + } + if stderr.Len() != 0 { + t.Fatalf("unexpected stderr: %s", stderr.String()) + } + if !strings.Contains(stdout.String(), "\"waypoints\"") { + t.Fatalf("unexpected stdout: %s", stdout.String()) + } +}