Skip to content

Commit 7326401

Browse files
committed
added --sort keys
1 parent 7ad9b7e commit 7326401

3 files changed

Lines changed: 122 additions & 18 deletions

File tree

.github/workflows/golang.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,6 @@ jobs:
5757
- name: Test
5858
run: go test -v -coverprofile=coverage.out ./...
5959
working-directory: ./golang
60+
61+
- name: Run Integration Test
62+
run: bash ./test-dummy.sh

golang/main.go

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,88 @@ package main
22

33
import (
44
"encoding/json"
5+
"flag"
56
"fmt"
67
"io"
78
"os"
89

910
"github.com/WebReflection/flatted/golang/pkg/flatted"
1011
)
1112

12-
func main() {
13-
stat, _ := os.Stdin.Stat()
14-
if (stat.Mode() & os.ModeCharDevice) != 0 {
15-
fmt.Fprintln(os.Stderr, "Usage: echo <circular-json> | flatted")
16-
os.Exit(1)
13+
// flatten reads standard JSON from r and writes flatted JSON to w.
14+
func flatten(r io.Reader, w io.Writer) error {
15+
input, err := io.ReadAll(r)
16+
if err != nil {
17+
return err
1718
}
18-
19-
input, err := io.ReadAll(os.Stdin)
19+
var data any
20+
if err := json.Unmarshal(input, &data); err != nil {
21+
return fmt.Errorf("invalid JSON input: %w", err)
22+
}
23+
s, err := flatted.Stringify(data, nil, nil)
2024
if err != nil {
21-
fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err)
22-
os.Exit(1)
25+
return err
2326
}
27+
fmt.Fprintln(w, s)
28+
return nil
29+
}
2430

25-
// Parse the flatted input
31+
// unflatten reads flatted JSON from r and writes standard JSON to w.
32+
func unflatten(r io.Reader, w io.Writer) error {
33+
input, err := io.ReadAll(r)
34+
if err != nil {
35+
return err
36+
}
2637
parsed, err := flatted.Parse(string(input), nil)
2738
if err != nil {
28-
fmt.Fprintf(os.Stderr, "Error parsing flatted data: %v\n", err)
29-
os.Exit(1)
39+
return fmt.Errorf("invalid flatted input: %w", err)
3040
}
31-
32-
// Convert to standard JSON for output.
33-
// Note: If the revived object is still circular, json.Marshal will error.
3441
output, err := json.MarshalIndent(parsed, "", " ")
3542
if err != nil {
36-
fmt.Fprintf(os.Stderr, "Error marshaling to JSON: %v\n", err)
37-
os.Exit(1)
43+
return err
3844
}
45+
fmt.Fprintln(w, string(output))
46+
return nil
47+
}
3948

40-
fmt.Println(string(output))
49+
func main() {
50+
var decompress bool
51+
flag.BoolVar(&decompress, "d", false, "decompress (unflatten)")
52+
flag.BoolVar(&decompress, "decompress", false, "decompress (unflatten)")
53+
flag.BoolVar(&decompress, "unflatten", false, "decompress (unflatten)")
54+
55+
flag.Usage = func() {
56+
fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]... [FILE]\n", os.Args[0])
57+
fmt.Fprintln(os.Stderr, "Flatten or unflatten circular JSON structures.")
58+
fmt.Fprintln(os.Stderr, "")
59+
fmt.Fprintln(os.Stderr, "Options:")
60+
flag.PrintDefaults()
61+
fmt.Fprintln(os.Stderr, "")
62+
fmt.Fprintln(os.Stderr, "If no FILE is provided, or if FILE is -, read from standard input.")
63+
}
64+
65+
flag.Parse()
66+
67+
var r io.Reader = os.Stdin
68+
if flag.NArg() > 0 && flag.Arg(0) != "-" {
69+
f, err := os.Open(flag.Arg(0))
70+
if err != nil {
71+
fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err)
72+
os.Exit(1)
73+
}
74+
defer f.Close()
75+
r = f
76+
}
77+
78+
var err error
79+
if decompress {
80+
err = unflatten(r, os.Stdout)
81+
} else {
82+
err = flatten(r, os.Stdout)
83+
}
84+
85+
if err != nil {
86+
fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err)
87+
os.Exit(1)
88+
}
4189
}

test-dummy.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash
2+
3+
# 1) Go to the golang directory and run a make build
4+
echo "Building flatted binary..."
5+
cd golang || exit 1
6+
make build || exit 1
7+
cd ..
8+
9+
# 2) normalize sha256sum test/65518.json and verify the hash
10+
ORIGINAL_HASH="c76a5329a11de440d28f8d8c4b37aafaa61bca9f1eb41a904b3d46312d5ab565"
11+
ACTUAL_HASH=$(cat test/65518.json | jq --sort-keys -r . | sha256sum | awk '{ print $1 }')
12+
13+
echo "Verifying checksum for test/65518.json..."
14+
if [ "$ACTUAL_HASH" == "$ORIGINAL_HASH" ]; then
15+
echo "Checksum verified successfully."
16+
else
17+
echo "Checksum mismatch!"
18+
echo "Expected: $ORIGINAL_HASH"
19+
echo "Actual: $ACTUAL_HASH"
20+
exit 1
21+
fi
22+
23+
# 3) Create a temp file, flatten the input, and verify the output hash
24+
TEMP_FILE=$(mktemp)
25+
trap 'rm -f "$TEMP_FILE"' EXIT
26+
27+
echo "Flattening test/65518.json and verifying output..."
28+
cat test/65518.json | ./golang/flatted | jq --sort-keys -r . > "$TEMP_FILE"
29+
30+
EXPECTED_OUTPUT_HASH="feacd401744cea2e8597b41ddb3bad1fe6e77e306979529ddea9bc72e3f30a14"
31+
ACTUAL_OUTPUT_HASH=$(sha256sum "$TEMP_FILE" | awk '{ print $1 }')
32+
33+
if [ "$ACTUAL_OUTPUT_HASH" == "$EXPECTED_OUTPUT_HASH" ]; then
34+
echo "Output checksum verified successfully."
35+
else
36+
echo "Output checksum mismatch!"
37+
echo "Expected: $EXPECTED_OUTPUT_HASH"
38+
echo "Actual: $ACTUAL_OUTPUT_HASH"
39+
exit 1
40+
fi
41+
42+
# 4) Unflatten the temp file and verify it matches the original normalized hash
43+
echo "Unflattening and verifying round-trip integrity..."
44+
ROUNDTRIP_HASH=$(cat "$TEMP_FILE" | ./golang/flatted -d | jq --sort-keys -r . | sha256sum | awk '{ print $1 }')
45+
46+
if [ "$ROUNDTRIP_HASH" == "$ORIGINAL_HASH" ]; then
47+
echo "Round-trip verification successful."
48+
else
49+
echo "Round-trip verification failed!"
50+
echo "Expected: $ORIGINAL_HASH"
51+
echo "Actual: $ROUNDTRIP_HASH"
52+
exit 1
53+
fi

0 commit comments

Comments
 (0)