github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_perimeter_test.go (about) 1 // Copyright 2020-2022 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package spatial 16 17 import ( 18 "math" 19 "testing" 20 21 "github.com/stretchr/testify/require" 22 23 "github.com/dolthub/go-mysql-server/sql" 24 "github.com/dolthub/go-mysql-server/sql/expression" 25 "github.com/dolthub/go-mysql-server/sql/types" 26 ) 27 28 func TestPerimeter(t *testing.T) { 29 t.Run("select perimeter of right triangle", func(t *testing.T) { 30 require := require.New(t) 31 polygon := types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 0, Y: 0}}}}} 32 f, err := NewPerimeter(expression.NewLiteral(polygon, types.PolygonType{})) 33 require.NoError(err) 34 35 v, err := f.Eval(sql.NewEmptyContext(), nil) 36 require.NoError(err) 37 require.Equal(1+1+math.Sqrt2, v) 38 }) 39 40 t.Run("select perimeter of unit square", func(t *testing.T) { 41 require := require.New(t) 42 polygon := types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}} 43 f, err := NewPerimeter(expression.NewLiteral(polygon, types.PolygonType{})) 44 require.NoError(err) 45 46 v, err := f.Eval(sql.NewEmptyContext(), nil) 47 require.NoError(err) 48 require.Equal(4.0, v) 49 }) 50 51 t.Run("select perimeter of some shape", func(t *testing.T) { 52 require := require.New(t) 53 polygon := types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 1, Y: 2}, {X: 3.2, Y: 4.5}, {X: -12.2, Y: 23}, {X: 55, Y: 88}, {X: 33, Y: 255.123}, {X: 17, Y: 2}, {X: 1, Y: 2}}}}} 54 f, err := NewPerimeter(expression.NewLiteral(polygon, types.PolygonType{})) 55 require.NoError(err) 56 57 v, err := f.Eval(sql.NewEmptyContext(), nil) 58 require.NoError(err) 59 require.Equal(559.0865562863385, v) 60 }) 61 62 t.Run("select perimeter of triangle with hole", func(t *testing.T) { 63 require := require.New(t) 64 line1 := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 3}, {X: 3, Y: 0}, {X: 0, Y: 0}}} 65 line2 := types.LineString{Points: []types.Point{{X: 1, Y: 1}, {X: 1, Y: 2}, {X: 2, Y: 1}, {X: 1, Y: 1}}} 66 polygon := types.Polygon{Lines: []types.LineString{line1, line2}} 67 f, err := NewPerimeter(expression.NewLiteral(polygon, types.PolygonType{})) 68 require.NoError(err) 69 70 v, err := f.Eval(sql.NewEmptyContext(), nil) 71 require.NoError(err) 72 perimeter1 := 3 + 3 + 3*math.Sqrt2 73 perimeter2 := 1 + 1 + math.Sqrt2 74 require.Equal(perimeter1+perimeter2, v) 75 }) 76 77 t.Run("select perimeter of NULL", func(t *testing.T) { 78 require := require.New(t) 79 f, err := NewPerimeter(expression.NewLiteral(nil, types.Null)) 80 require.NoError(err) 81 82 v, err := f.Eval(sql.NewEmptyContext(), nil) 83 require.NoError(err) 84 require.Equal(nil, v) 85 }) 86 87 t.Run("select length of wrong type", func(t *testing.T) { 88 require := require.New(t) 89 f, err := NewPerimeter(expression.NewLiteral("abc", types.Text)) 90 require.NoError(err) 91 _, err = f.Eval(sql.NewEmptyContext(), nil) 92 require.Error(err) 93 }) 94 }