package netmap_test import ( "strings" "testing" . "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test" "github.com/stretchr/testify/require" ) func TestPlacementPolicyEncoding(t *testing.T) { v := netmaptest.PlacementPolicy() t.Run("binary", func(t *testing.T) { var v2 PlacementPolicy require.NoError(t, v2.Unmarshal(v.Marshal())) require.Equal(t, v, v2) }) t.Run("json", func(t *testing.T) { data, err := v.MarshalJSON() require.NoError(t, err) var v2 PlacementPolicy require.NoError(t, v2.UnmarshalJSON(data)) require.Equal(t, v, v2) }) } func TestPlacementPolicyWriteString(t *testing.T) { testCases := []struct { name string input string output string // If the output is empty, make it equal to input. }{ { name: "no compound operators", input: `REP 1 CBF 1 SELECT 1 FROM Color FILTER Color EQ Red AS Color`, }, { name: "no brackets in single level same-operator chain", input: `REP 1 CBF 1 SELECT 1 FROM Color FILTER Color EQ Red OR Color EQ Blue OR Color EQ Green AS Color`, }, { name: "no brackets aroung higher precedence op", input: `REP 1 CBF 1 SELECT 1 FROM Color FILTER Color EQ Red OR Color EQ Blue AND Color NE Green AS Color`, }, { name: "no brackets aroung higher precedence op, even if present in the input", input: `REP 1 CBF 1 SELECT 1 FROM Color FILTER Color EQ Red OR (Color EQ Blue AND Color NE Green) AS Color`, output: `REP 1 CBF 1 SELECT 1 FROM Color FILTER Color EQ Red OR Color EQ Blue AND Color NE Green AS Color`, }, { name: "brackets aroung lower precedence op", input: `REP 1 CBF 1 SELECT 1 FROM Color FILTER (Color EQ Red OR Color EQ Blue) AND Color NE Green AS Color`, }, { name: "no extra brackets for bracketed same-operator chain", input: `REP 1 CBF 1 SELECT 1 FROM Color FILTER (Color EQ Red OR Color EQ Blue OR Color EQ Yellow) AND Color NE Green AS Color`, }, { name: "non-ascii attributes in SELECT IN", input: `REP 1 CBF 1 SELECT 1 IN SAME 'Цвет' FROM Colorful FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful`, }, } for _, tc := range testCases { var p PlacementPolicy require.NoError(t, p.DecodeString(tc.input)) var sb strings.Builder require.NoError(t, p.WriteStringTo(&sb)) if tc.output == "" { require.Equal(t, tc.input, sb.String()) } else { require.Equal(t, tc.output, sb.String()) var p1 PlacementPolicy require.NoError(t, p1.DecodeString(tc.output)) require.Equal(t, p, p1) } } } func TestDecodeSelectFilterExpr(t *testing.T) { for _, s := range []string{ "SELECT 1 FROM *", "FILTER Color EQ 'Red' AS RedNode", ` FILTER Color EQ 'Red' AS RedNode FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode `, ` SELECT 1 FROM RedCircleNode FILTER Color EQ 'Red' AS RedNode FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode `, ` CBF 1 SELECT 1 FROM RedCircleNode FILTER Color EQ 'Red' AS RedNode FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode `, ` CBF 1 SELECT 1 FROM R FILTER Color LIKE 'R' AS R `, ` CBF 1 SELECT 1 IN SAME 'Цвет' FROM Colorful FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful `, } { _, err := DecodeSelectFilterString(s) require.NoError(t, err) } }