github.com/weaviate/weaviate@v1.24.6/entities/moduletools/vectorizable_props_comparator_test.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package moduletools
    13  
    14  import (
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/google/uuid"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/weaviate/weaviate/entities/models"
    21  	"github.com/weaviate/weaviate/entities/schema"
    22  )
    23  
    24  func TestVectorizablePropsComparator(t *testing.T) {
    25  	propsSchema := createPropsSchema()
    26  	nextProps := createNextProps()
    27  	prevProps := createPrevProps()
    28  	prevVector := []float32{1, 2, 3}
    29  	// nil prevVectors
    30  	var prevVectors models.Vectors
    31  
    32  	t.Run("iterator", func(t *testing.T) {
    33  		comp := NewVectorizablePropsComparator(propsSchema, nextProps, prevProps, prevVector, prevVectors)
    34  
    35  		t.Run("returns props in asc order", func(t *testing.T) {
    36  			expectedNames := []string{"blob", "text", "texts"}
    37  			names := []string{}
    38  
    39  			it := comp.PropsIterator()
    40  			for propName, _, ok := it.Next(); ok; propName, _, ok = it.Next() {
    41  				names = append(names, propName)
    42  			}
    43  
    44  			assert.Equal(t, expectedNames, names)
    45  		})
    46  
    47  		t.Run("returns values of next props", func(t *testing.T) {
    48  			expectedValues := []interface{}{
    49  				nextProps["blob"],
    50  				nextProps["text"],
    51  				nextProps["texts"],
    52  			}
    53  			values := []interface{}{}
    54  
    55  			it := comp.PropsIterator()
    56  			for _, propValue, ok := it.Next(); ok; _, propValue, ok = it.Next() {
    57  				values = append(values, propValue)
    58  			}
    59  
    60  			assert.Equal(t, expectedValues, values)
    61  		})
    62  	})
    63  
    64  	t.Run("returns prev vector", func(t *testing.T) {
    65  		comp := NewVectorizablePropsComparator(propsSchema, nextProps, prevProps, prevVector, prevVectors)
    66  
    67  		vector := comp.PrevVector()
    68  
    69  		assert.Equal(t, prevVector, vector)
    70  	})
    71  
    72  	t.Run("considers non-vectorizable props as not changed", func(t *testing.T) {
    73  		t.Run("all different", func(t *testing.T) {
    74  			comp := NewVectorizablePropsComparator(propsSchema, nextProps, prevProps, prevVector, prevVectors)
    75  
    76  			for _, propSchema := range propsSchema {
    77  				switch propSchema.Name {
    78  				case "blob", "text", "texts":
    79  					assert.True(t, comp.IsChanged(propSchema.Name))
    80  				default:
    81  					assert.False(t, comp.IsChanged(propSchema.Name))
    82  				}
    83  			}
    84  		})
    85  
    86  		t.Run("next nils", func(t *testing.T) {
    87  			comp := NewVectorizablePropsComparator(propsSchema, map[string]interface{}{}, prevProps, prevVector, prevVectors)
    88  
    89  			for _, propSchema := range propsSchema {
    90  				switch propSchema.Name {
    91  				case "blob", "text", "texts":
    92  					assert.True(t, comp.IsChanged(propSchema.Name))
    93  				default:
    94  					assert.False(t, comp.IsChanged(propSchema.Name))
    95  				}
    96  			}
    97  		})
    98  
    99  		t.Run("prev nils", func(t *testing.T) {
   100  			comp := NewVectorizablePropsComparator(propsSchema, nextProps, map[string]interface{}{}, prevVector, prevVectors)
   101  
   102  			for _, propSchema := range propsSchema {
   103  				switch propSchema.Name {
   104  				case "blob", "text", "texts":
   105  					assert.True(t, comp.IsChanged(propSchema.Name))
   106  				default:
   107  					assert.False(t, comp.IsChanged(propSchema.Name))
   108  				}
   109  			}
   110  		})
   111  	})
   112  
   113  	t.Run("considers vectorizable props not changed", func(t *testing.T) {
   114  		missingProps := map[string]interface{}{}
   115  		nilProps := map[string]interface{}{
   116  			"blob":  nil,
   117  			"text":  nil,
   118  			"texts": nil,
   119  		}
   120  		emptyArrayProps := map[string]interface{}{
   121  			"texts": []string{},
   122  		}
   123  		emptyIfArrayProps := map[string]interface{}{
   124  			"texts": []interface{}{},
   125  		}
   126  
   127  		t.Run("nil -> nil", func(t *testing.T) {
   128  			comp := NewVectorizablePropsComparator(propsSchema, nilProps, nilProps, prevVector, prevVectors)
   129  
   130  			for _, propName := range []string{"blob", "text", "texts"} {
   131  				assert.False(t, comp.IsChanged(propName))
   132  			}
   133  		})
   134  
   135  		t.Run("missing -> nil", func(t *testing.T) {
   136  			comp := NewVectorizablePropsComparator(propsSchema, nilProps, missingProps, prevVector, prevVectors)
   137  
   138  			for _, propName := range []string{"blob", "text", "texts"} {
   139  				assert.False(t, comp.IsChanged(propName))
   140  			}
   141  		})
   142  
   143  		t.Run("nil -> missing", func(t *testing.T) {
   144  			comp := NewVectorizablePropsComparator(propsSchema, missingProps, nilProps, prevVector, prevVectors)
   145  
   146  			for _, propName := range []string{"blob", "text", "texts"} {
   147  				assert.False(t, comp.IsChanged(propName))
   148  			}
   149  		})
   150  
   151  		t.Run("missing -> missing", func(t *testing.T) {
   152  			comp := NewVectorizablePropsComparator(propsSchema, missingProps, missingProps, prevVector, prevVectors)
   153  
   154  			for _, propName := range []string{"blob", "text", "texts"} {
   155  				assert.False(t, comp.IsChanged(propName))
   156  			}
   157  		})
   158  
   159  		t.Run("missing -> empty array", func(t *testing.T) {
   160  			comp := NewVectorizablePropsComparator(propsSchema, emptyArrayProps, missingProps, prevVector, prevVectors)
   161  
   162  			for _, propName := range []string{"texts"} {
   163  				assert.False(t, comp.IsChanged(propName))
   164  			}
   165  		})
   166  
   167  		t.Run("nil -> empty array", func(t *testing.T) {
   168  			comp := NewVectorizablePropsComparator(propsSchema, emptyArrayProps, nilProps, prevVector, prevVectors)
   169  
   170  			for _, propName := range []string{"texts"} {
   171  				assert.False(t, comp.IsChanged(propName))
   172  			}
   173  		})
   174  
   175  		t.Run("empty array -> missing", func(t *testing.T) {
   176  			comp := NewVectorizablePropsComparator(propsSchema, missingProps, emptyArrayProps, prevVector, prevVectors)
   177  
   178  			for _, propName := range []string{"texts"} {
   179  				assert.False(t, comp.IsChanged(propName))
   180  			}
   181  		})
   182  
   183  		t.Run("empty array -> nil", func(t *testing.T) {
   184  			comp := NewVectorizablePropsComparator(propsSchema, nilProps, emptyArrayProps, prevVector, prevVectors)
   185  
   186  			for _, propName := range []string{"texts"} {
   187  				assert.False(t, comp.IsChanged(propName))
   188  			}
   189  		})
   190  
   191  		t.Run("empty interface array -> missing", func(t *testing.T) {
   192  			comp := NewVectorizablePropsComparator(propsSchema, missingProps, emptyIfArrayProps, prevVector, prevVectors)
   193  
   194  			for _, propName := range []string{"texts"} {
   195  				assert.False(t, comp.IsChanged(propName))
   196  			}
   197  		})
   198  
   199  		t.Run("empty interface array -> nil", func(t *testing.T) {
   200  			comp := NewVectorizablePropsComparator(propsSchema, nilProps, emptyIfArrayProps, prevVector, prevVectors)
   201  
   202  			for _, propName := range []string{"texts"} {
   203  				assert.False(t, comp.IsChanged(propName))
   204  			}
   205  		})
   206  
   207  		t.Run("empty interface array -> empty array", func(t *testing.T) {
   208  			comp := NewVectorizablePropsComparator(propsSchema, emptyArrayProps, emptyIfArrayProps, prevVector, prevVectors)
   209  
   210  			for _, propName := range []string{"texts"} {
   211  				assert.False(t, comp.IsChanged(propName))
   212  			}
   213  		})
   214  	})
   215  
   216  	t.Run("considers vectorizable props changed", func(t *testing.T) {
   217  		textPropsABC := map[string]interface{}{
   218  			"texts": []string{"aaa", "bbb", "ccc"},
   219  		}
   220  		textPropsABCD := map[string]interface{}{
   221  			"texts": []string{"aaa", "bbb", "ccc", "ddd"},
   222  		}
   223  		textPropsCBA := map[string]interface{}{
   224  			"texts": []string{"ccc", "bbb", "aaa"},
   225  		}
   226  
   227  		t.Run("different array sizes (1)", func(t *testing.T) {
   228  			comp := NewVectorizablePropsComparator(propsSchema, textPropsABCD, textPropsABC, prevVector, prevVectors)
   229  
   230  			for _, propName := range []string{"texts"} {
   231  				assert.True(t, comp.IsChanged(propName))
   232  			}
   233  		})
   234  
   235  		t.Run("different array sizes (2)", func(t *testing.T) {
   236  			comp := NewVectorizablePropsComparator(propsSchema, textPropsABC, textPropsABCD, prevVector, prevVectors)
   237  
   238  			for _, propName := range []string{"texts"} {
   239  				assert.True(t, comp.IsChanged(propName))
   240  			}
   241  		})
   242  
   243  		t.Run("different array order", func(t *testing.T) {
   244  			comp := NewVectorizablePropsComparator(propsSchema, textPropsCBA, textPropsABC, prevVector, prevVectors)
   245  
   246  			for _, propName := range []string{"texts"} {
   247  				assert.True(t, comp.IsChanged(propName))
   248  			}
   249  		})
   250  
   251  		// none of following should happen
   252  
   253  		missingProps := map[string]interface{}{}
   254  		nilProps := map[string]interface{}{
   255  			"texts": nil,
   256  		}
   257  		emptyArrayProps := map[string]interface{}{
   258  			"texts": []string{},
   259  		}
   260  		emptyIfArrayProps := map[string]interface{}{
   261  			"texts": []interface{}{},
   262  		}
   263  		arrayProps := map[string]interface{}{
   264  			"texts": []string{"txt1", "txt2"},
   265  		}
   266  		ifArrayProps := map[string]interface{}{
   267  			"texts": []interface{}{"txt1", "txt2"},
   268  		}
   269  
   270  		t.Run("interface array -> array", func(t *testing.T) {
   271  			comp := NewVectorizablePropsComparator(propsSchema, arrayProps, ifArrayProps, prevVector, prevVectors)
   272  
   273  			for _, propName := range []string{"texts"} {
   274  				assert.True(t, comp.IsChanged(propName))
   275  			}
   276  		})
   277  
   278  		t.Run("array -> interface array", func(t *testing.T) {
   279  			comp := NewVectorizablePropsComparator(propsSchema, ifArrayProps, arrayProps, prevVector, prevVectors)
   280  
   281  			for _, propName := range []string{"texts"} {
   282  				assert.True(t, comp.IsChanged(propName))
   283  			}
   284  		})
   285  
   286  		t.Run("missing -> empty interface array", func(t *testing.T) {
   287  			comp := NewVectorizablePropsComparator(propsSchema, emptyIfArrayProps, missingProps, prevVector, prevVectors)
   288  
   289  			for _, propName := range []string{"texts"} {
   290  				assert.True(t, comp.IsChanged(propName))
   291  			}
   292  		})
   293  
   294  		t.Run("nil -> empty interface array", func(t *testing.T) {
   295  			comp := NewVectorizablePropsComparator(propsSchema, emptyIfArrayProps, nilProps, prevVector, prevVectors)
   296  
   297  			for _, propName := range []string{"texts"} {
   298  				assert.True(t, comp.IsChanged(propName))
   299  			}
   300  		})
   301  
   302  		t.Run("empty array -> empty interface array", func(t *testing.T) {
   303  			comp := NewVectorizablePropsComparator(propsSchema, emptyIfArrayProps, emptyArrayProps, prevVector, prevVectors)
   304  
   305  			for _, propName := range []string{"texts"} {
   306  				assert.True(t, comp.IsChanged(propName))
   307  			}
   308  		})
   309  	})
   310  }
   311  
   312  func TestVectorizablePropsComparatorDummy(t *testing.T) {
   313  	propsSchema := createPropsSchema()
   314  	nextProps := createNextProps()
   315  
   316  	t.Run("iterator", func(t *testing.T) {
   317  		comp := NewVectorizablePropsComparatorDummy(propsSchema, nextProps)
   318  
   319  		t.Run("returns props in asc order", func(t *testing.T) {
   320  			expectedNames := []string{"blob", "text", "texts"}
   321  			names := []string{}
   322  
   323  			it := comp.PropsIterator()
   324  			for propName, _, ok := it.Next(); ok; propName, _, ok = it.Next() {
   325  				names = append(names, propName)
   326  			}
   327  
   328  			assert.Equal(t, expectedNames, names)
   329  		})
   330  
   331  		t.Run("returns values of next props", func(t *testing.T) {
   332  			expectedValues := []interface{}{
   333  				nextProps["blob"],
   334  				nextProps["text"],
   335  				nextProps["texts"],
   336  			}
   337  			values := []interface{}{}
   338  
   339  			it := comp.PropsIterator()
   340  			for _, propValue, ok := it.Next(); ok; _, propValue, ok = it.Next() {
   341  				values = append(values, propValue)
   342  			}
   343  
   344  			assert.Equal(t, expectedValues, values)
   345  		})
   346  	})
   347  
   348  	t.Run("returns no prev vector", func(t *testing.T) {
   349  		comp := NewVectorizablePropsComparatorDummy(propsSchema, nextProps)
   350  
   351  		vector := comp.PrevVector()
   352  
   353  		assert.Nil(t, vector)
   354  	})
   355  
   356  	t.Run("considers non-vectorizable props as not changed", func(t *testing.T) {
   357  		comp := NewVectorizablePropsComparatorDummy(propsSchema, nextProps)
   358  
   359  		for _, propSchema := range propsSchema {
   360  			switch propSchema.Name {
   361  			case "blob", "text", "texts":
   362  				assert.True(t, comp.IsChanged(propSchema.Name))
   363  			default:
   364  				assert.False(t, comp.IsChanged(propSchema.Name))
   365  			}
   366  		}
   367  	})
   368  
   369  	t.Run("considers vectorizable props not changed", func(t *testing.T) {
   370  		t.Run("nil", func(t *testing.T) {
   371  			comp := NewVectorizablePropsComparatorDummy(propsSchema, map[string]interface{}{
   372  				"blob":  nil,
   373  				"text":  nil,
   374  				"texts": nil,
   375  			})
   376  
   377  			for _, propName := range []string{"blob", "text", "texts"} {
   378  				assert.False(t, comp.IsChanged(propName))
   379  			}
   380  		})
   381  
   382  		t.Run("missing", func(t *testing.T) {
   383  			comp := NewVectorizablePropsComparatorDummy(propsSchema, map[string]interface{}{})
   384  
   385  			for _, propName := range []string{"blob", "text", "texts"} {
   386  				assert.False(t, comp.IsChanged(propName))
   387  			}
   388  		})
   389  
   390  		t.Run("empty array", func(t *testing.T) {
   391  			comp := NewVectorizablePropsComparatorDummy(propsSchema, map[string]interface{}{
   392  				"texts": []string{},
   393  			})
   394  
   395  			for _, propName := range []string{"texts"} {
   396  				assert.False(t, comp.IsChanged(propName))
   397  			}
   398  		})
   399  	})
   400  }
   401  
   402  func createPropsSchema() []*models.Property {
   403  	return []*models.Property{
   404  		{
   405  			Name:     "text",
   406  			DataType: schema.DataTypeText.PropString(),
   407  		},
   408  		{
   409  			Name:     "texts",
   410  			DataType: schema.DataTypeTextArray.PropString(),
   411  		},
   412  		{
   413  			Name:     "int",
   414  			DataType: schema.DataTypeInt.PropString(),
   415  		},
   416  		{
   417  			Name:     "ints",
   418  			DataType: schema.DataTypeIntArray.PropString(),
   419  		},
   420  		{
   421  			Name:     "number",
   422  			DataType: schema.DataTypeNumber.PropString(),
   423  		},
   424  		{
   425  			Name:     "numbers",
   426  			DataType: schema.DataTypeNumberArray.PropString(),
   427  		},
   428  		{
   429  			Name:     "boolean",
   430  			DataType: schema.DataTypeBoolean.PropString(),
   431  		},
   432  		{
   433  			Name:     "booleans",
   434  			DataType: schema.DataTypeBooleanArray.PropString(),
   435  		},
   436  		{
   437  			Name:     "date",
   438  			DataType: schema.DataTypeDate.PropString(),
   439  		},
   440  		{
   441  			Name:     "dates",
   442  			DataType: schema.DataTypeDateArray.PropString(),
   443  		},
   444  		{
   445  			Name:     "uuid",
   446  			DataType: schema.DataTypeUUID.PropString(),
   447  		},
   448  		{
   449  			Name:     "uuids",
   450  			DataType: schema.DataTypeUUIDArray.PropString(),
   451  		},
   452  		{
   453  			Name:     "phone",
   454  			DataType: schema.DataTypePhoneNumber.PropString(),
   455  		},
   456  		{
   457  			Name:     "geo",
   458  			DataType: schema.DataTypeGeoCoordinates.PropString(),
   459  		},
   460  		{
   461  			Name:     "blob",
   462  			DataType: schema.DataTypeBlob.PropString(),
   463  		},
   464  		{
   465  			Name:     "object",
   466  			DataType: schema.DataTypeObject.PropString(),
   467  			NestedProperties: []*models.NestedProperty{
   468  				{
   469  					Name:     "n_text",
   470  					DataType: schema.DataTypeText.PropString(),
   471  				},
   472  			},
   473  		},
   474  		{
   475  			Name:     "objects",
   476  			DataType: schema.DataTypeObjectArray.PropString(),
   477  			NestedProperties: []*models.NestedProperty{
   478  				{
   479  					Name:     "n_text",
   480  					DataType: schema.DataTypeText.PropString(),
   481  				},
   482  			},
   483  		},
   484  	}
   485  }
   486  
   487  const (
   488  	image  = "iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAACrElEQVR4nOyUS0wUeRDGv37N9Dx6GJiF3ckOWUhgQ7LsssthN+xlA9k9bDBelJM3n2AkwYOCXhC9GGLiTeOBxKPxYsLBdwwXHzFRTAg4ikh05DGODE73DP36P0z3BEQT9CAXEyvppCtV9ctX1dUlc86xmSZuKu2rBcqAE/58qRsEIH0KKDIy0UHMgbuOvu1ZGbyhCUTvnKSl3vvMGf/H89cC3ldmLJeizvlTwHQX5xUio3mmRkc8lfZGxOJ8Upcjf2ii9B04a7yghPceEuXvX/lAfbnrlijq7WbpMTh3oYZbaKzyqgd0NgJmZ0I6o44mBZKIxP8Go4l7WuJsm99WoThVbVtpEMqgKHEIAXNtDAU385/D9K2eo4iR0bhSdx0AL7kclDAwaw4OG0co+me117EPLLoMKw4DZYDCKWS3hAU323C7ODa8THKdebYESZBQI9bsD0mRK23R9oOGCxACMAb/RWLEV+ADdZdzL6EMJCiaprRnZuiBy6HmaA6UlkepBFSklOT/ztJYR79B5J8UQBLKNUFG3wMLLmAQIG8DBcJQJ1iYzZkqFRmQ54DOAMphaw7SqdeATIIvSkCWAz+GAVUD1PUK3zjJ7OzbJ79aBFBlCsMqQlrQICwWAFcFZwEf6PeXphAaguBVABWAnBNECrWgdnzRm62/h//+fOZARfi3cUECLMbwvGBDegjImSi0pURxoGX7iaOtXUOxfJUhZcIQbwrIGIAaCKE+UQ+TVE80/dDf40v01sZ7XOrIo1PHj3RfCpq9owFeueMw/71vOD3xcu6X1ZypzHxTa8+xSW3LLr7voswHr9VYN56eHHSpHVjNET4+X4tGuvFO5ly3bTQUOpt3no5FQsb6uLFiRS4/GukLVkwn/qrdPZKMNU9+8At9u4dfbO8CAAD///eAU+2FY+BGAAAAAElFTkSuQmCC"
   489  	image2 = "iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAC1UlEQVR4nNyUS0h8dRTHv/f+7tz/nTv6d2YaXQgq+KSHaQQRLiQyGmnRRmgRSWRtiswWEkUhGNFGKouiRbRrEURgIWS4SBBFy7JclEzqZGaJr3nd9+8Vd6YmEbGFburAvZtzzufc8z1frialxHWHeu3E/wX0SsPONYsoD2bGqPXEkmC77Zd28v0mbj2+JLxPRgGuXwRVOVtPU3d8VWJtWol03Ct49s7LmIxm2ij9sU/I+XeC4uga879+AIBShXrOuy/R4PW5gG51l3Ifg9INiH/xmhBcWrlvUTycAWXZbuZPz7uF918Nc1r4KhY/TYegwC8AIEjq7dDVKlQRYCnK7aYIif2qQjsBILkEnEBCiCNIax43k30g2vpDUWCiDLUDT7GdU3AOKIoKkzkgupSOsBoyzuprVOQeA0hUgfRU1fyoK9r3criIRQEuAME5iJ+HoQaofqnNpCz8VQAIxAILc3Tx0eXc8ocl4d3yC83CEy5qSK3ReaPjKaO4NtQj3dnbKSBFZR1DMKhC/AMtMSBPASHLA+BZLt4rfvPI90iBwQccF/ApoDMsxTegEyPREvw2/GQeaDGBuA7USA6tMkGWoblAkacUOLABi0ncZjhgeQ2gOrTDEEoAoVaENDhYmwC/AbgM2CwAdTpws06Hwiq7lqERfWAhs7/SX7aDApR8B/R3ArIbChYFhBGeu6IPF5A/c4hWDbIViBAViZpG2KIBBD0LVUsNdE5OprveGIMas2wqsZ33QbMKtD9qYR4nvKn7hke3xt9ufPPBkafNXNwhBybYpop9V0U8loJCEk7SHHrh7ubxF8uihlf8+zksZZvfWkzPPvs5kfe8Mih7npnKfLe913u25oedvTt6RyZ+uuu5fvn8Z5r8YOXhL4+sndazNcpFHs+cfNVvB8f1t9YPzhlarX0+7zPb3Dz6YtCMJE87UvcvnM9fCL1q/Pf/p1eKPwMAAP//lJuHtr5ZxxcAAAAASUVORK5CYII="
   490  )
   491  
   492  func createPrevProps() map[string]interface{} {
   493  	return map[string]interface{}{
   494  		"text":     "prev text",
   495  		"texts":    []string{"prev texts_1", "prev texts_2"},
   496  		"int":      float64(-1),
   497  		"ints":     []float64{-2, -3},
   498  		"number":   float64(-1.1),
   499  		"numbers":  []float64{-2.2, -3.3},
   500  		"boolean":  false,
   501  		"booleans": []bool{true, true},
   502  		"date":     time.Unix(1707332399, 0),
   503  		"dates":    []time.Time{time.Unix(1707335999, 0), time.Unix(1707339599, 0)},
   504  		"uuid":     uuid.MustParse("018d85e5-eec6-71bb-9a0f-f7cb545784c3"),
   505  		"uuids": []uuid.UUID{
   506  			uuid.MustParse("018d85e6-f7c9-74c4-b960-f1fd74bb2d3c"),
   507  			uuid.MustParse("018d85e7-1b69-7e86-a487-bab1dec5d2f4"),
   508  		},
   509  		"phone": &models.PhoneNumber{
   510  			DefaultCountry: "PL",
   511  			Input:          "123456789",
   512  		},
   513  		"geo": &models.GeoCoordinates{
   514  			Latitude:  ptrFloat32(51.107882),
   515  			Longitude: ptrFloat32(17.038537),
   516  		},
   517  		"blob": image,
   518  		"object": map[string]interface{}{
   519  			"n_text": "prev n_text",
   520  		},
   521  		"objects": []map[string]interface{}{
   522  			{"n_text": "prev n_text_0"},
   523  			{"n_text": "prev n_text_1"},
   524  		},
   525  	}
   526  }
   527  
   528  func createNextProps() map[string]interface{} {
   529  	return map[string]interface{}{
   530  		"text":     "text",
   531  		"texts":    []string{"texts_1", "texts_2"},
   532  		"int":      float64(1),
   533  		"ints":     []float64{2, 3},
   534  		"number":   float64(1.1),
   535  		"numbers":  []float64{2.2, 3.3},
   536  		"boolean":  true,
   537  		"booleans": []bool{false, false},
   538  		"date":     time.Unix(1707332400, 0),
   539  		"dates":    []time.Time{time.Unix(1707336000, 0), time.Unix(1707339600, 0)},
   540  		"uuid":     uuid.MustParse("a2578e23-f665-4f04-97f1-5e56f5d4cea4"),
   541  		"uuids": []uuid.UUID{
   542  			uuid.MustParse("037a19a2-aeba-40cf-9a6b-60e36f10b030"),
   543  			uuid.MustParse("6e92f90c-99c9-4579-9711-17015c361e07"),
   544  		},
   545  		"phone": &models.PhoneNumber{
   546  			DefaultCountry: "PL",
   547  			Input:          "100000000",
   548  		},
   549  		"geo": &models.GeoCoordinates{
   550  			Latitude:  ptrFloat32(51.107883),
   551  			Longitude: ptrFloat32(17.038538),
   552  		},
   553  		"blob": image2,
   554  		"object": map[string]interface{}{
   555  			"n_text": "n_text",
   556  		},
   557  		"objects": []map[string]interface{}{
   558  			{"n_text": "n_text_0"},
   559  			{"n_text": "n_text_1"},
   560  		},
   561  	}
   562  }
   563  
   564  func ptrFloat32(f float32) *float32 {
   565  	return &f
   566  }