github.com/mithrandie/csvq@v1.18.1/lib/query/view_map_test.go (about)

     1  package query
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/mithrandie/csvq/lib/parser"
    10  	"github.com/mithrandie/csvq/lib/value"
    11  )
    12  
    13  var viewMapExistsTests = []struct {
    14  	Name   string
    15  	Path   string
    16  	Result bool
    17  }{
    18  	{
    19  		Name:   "ViewMap Exists",
    20  		Path:   strings.ToUpper("/path/to/table1.csv"),
    21  		Result: true,
    22  	},
    23  	{
    24  		Name:   "ViewMap Exists Not Exist",
    25  		Path:   strings.ToUpper("/path/to/notexist.csv"),
    26  		Result: false,
    27  	},
    28  }
    29  
    30  func TestViewMap_Exists(t *testing.T) {
    31  	viewMap := GenerateViewMap([]*View{
    32  		{
    33  			Header:    NewHeader("table1", []string{"column1", "column2"}),
    34  			RecordSet: []Record{},
    35  			FileInfo: &FileInfo{
    36  				Path:      "/path/to/table1.csv",
    37  				Delimiter: ',',
    38  			},
    39  		},
    40  	})
    41  
    42  	for _, v := range viewMapExistsTests {
    43  		result := viewMap.Exists(v.Path)
    44  		if result != v.Result {
    45  			t.Errorf("%s: result = %t, want %t", v.Name, result, v.Result)
    46  		}
    47  	}
    48  }
    49  
    50  var viewMapGetTests = []struct {
    51  	Name   string
    52  	Path   string
    53  	Result *View
    54  	Error  string
    55  }{
    56  	{
    57  		Name: "ViewMap Get",
    58  		Path: strings.ToUpper("/path/to/table1.csv"),
    59  		Result: &View{
    60  			Header: NewHeader("table1", []string{"column1", "column2"}),
    61  			RecordSet: []Record{
    62  				NewRecord([]value.Primary{
    63  					value.NewString("1"),
    64  					value.NewString("str1"),
    65  				}),
    66  				NewRecord([]value.Primary{
    67  					value.NewString("2"),
    68  					value.NewString("str2"),
    69  				}),
    70  			},
    71  			FileInfo: &FileInfo{
    72  				Path:      "/path/to/table1.csv",
    73  				Delimiter: ',',
    74  			},
    75  		},
    76  	},
    77  	{
    78  		Name:  "ViewMap Get Not Loaded Error",
    79  		Path:  strings.ToUpper("/path/to/table2.csv"),
    80  		Error: "table not loaded",
    81  	},
    82  }
    83  
    84  func TestViewMap_Get(t *testing.T) {
    85  	viewMap := GenerateViewMap([]*View{
    86  		{
    87  			Header: NewHeader("table1", []string{"column1", "column2"}),
    88  			RecordSet: []Record{
    89  				NewRecord([]value.Primary{
    90  					value.NewString("1"),
    91  					value.NewString("str1"),
    92  				}),
    93  				NewRecord([]value.Primary{
    94  					value.NewString("2"),
    95  					value.NewString("str2"),
    96  				}),
    97  			},
    98  			FileInfo: &FileInfo{
    99  				Path:      "/path/to/table1.csv",
   100  				Delimiter: ',',
   101  			},
   102  		},
   103  	})
   104  
   105  	for _, v := range viewMapGetTests {
   106  		view, err := viewMap.Get(v.Path)
   107  		if err != nil {
   108  			if len(v.Error) < 1 {
   109  				t.Errorf("%s: unexpected error %q", v.Name, err)
   110  			} else if err.Error() != v.Error {
   111  				t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error)
   112  			}
   113  			continue
   114  		}
   115  		if 0 < len(v.Error) {
   116  			t.Errorf("%s: no error, want error %q", v.Name, v.Error)
   117  			continue
   118  		}
   119  		if !reflect.DeepEqual(view, v.Result) {
   120  			t.Errorf("%s: view = %v, want %v", v.Name, view, v.Result)
   121  		}
   122  	}
   123  }
   124  
   125  var viewMapGetWithInternalIdTests = []struct {
   126  	Name   string
   127  	Path   string
   128  	Result *View
   129  	Error  string
   130  }{
   131  	{
   132  		Name: "ViewMap GetWithInternalId",
   133  		Path: strings.ToUpper("/path/to/table1.csv"),
   134  		Result: &View{
   135  			Header: NewHeaderWithId("table1", []string{"column1", "column2"}),
   136  			RecordSet: []Record{
   137  				NewRecordWithId(0, []value.Primary{
   138  					value.NewString("1"),
   139  					value.NewString("str1"),
   140  				}),
   141  				NewRecordWithId(1, []value.Primary{
   142  					value.NewString("2"),
   143  					value.NewString("str2"),
   144  				}),
   145  			},
   146  			FileInfo: &FileInfo{
   147  				Path:      "/path/to/table1.csv",
   148  				Delimiter: ',',
   149  			},
   150  		},
   151  	},
   152  	{
   153  		Name:  "ViewMap GetWithInternalId Not Loaded Error",
   154  		Path:  strings.ToUpper("/path/to/table2.csv"),
   155  		Error: "table not loaded",
   156  	},
   157  }
   158  
   159  func TestViewMap_GetWithInternalId(t *testing.T) {
   160  	viewMap := GenerateViewMap([]*View{
   161  		{
   162  			Header: NewHeader("table1", []string{"column1", "column2"}),
   163  			RecordSet: []Record{
   164  				NewRecord([]value.Primary{
   165  					value.NewString("1"),
   166  					value.NewString("str1"),
   167  				}),
   168  				NewRecord([]value.Primary{
   169  					value.NewString("2"),
   170  					value.NewString("str2"),
   171  				}),
   172  			},
   173  			FileInfo: &FileInfo{
   174  				Path:      "/path/to/table1.csv",
   175  				Delimiter: ',',
   176  			},
   177  		},
   178  	})
   179  
   180  	for _, v := range viewMapGetWithInternalIdTests {
   181  		view, err := viewMap.GetWithInternalId(context.Background(), v.Path, TestTx.Flags)
   182  		if err != nil {
   183  			if len(v.Error) < 1 {
   184  				t.Errorf("%s: unexpected error %q", v.Name, err)
   185  			} else if err.Error() != v.Error {
   186  				t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error)
   187  			}
   188  			continue
   189  		}
   190  		if 0 < len(v.Error) {
   191  			t.Errorf("%s: no error, want error %q", v.Name, v.Error)
   192  			continue
   193  		}
   194  		if !reflect.DeepEqual(view, v.Result) {
   195  			t.Errorf("%s: view = %v, want %v", v.Name, view, v.Result)
   196  		}
   197  	}
   198  }
   199  
   200  var viewMapSetTests = []struct {
   201  	Name    string
   202  	SetView *View
   203  	Result  ViewMap
   204  }{
   205  	{
   206  		Name: "ViewMap Set",
   207  		SetView: &View{
   208  			Header: NewHeader("table1", []string{"column1", "column2"}),
   209  			RecordSet: []Record{
   210  				NewRecord([]value.Primary{
   211  					value.NewString("1"),
   212  					value.NewString("str1"),
   213  				}),
   214  				NewRecord([]value.Primary{
   215  					value.NewString("2"),
   216  					value.NewString("str2"),
   217  				}),
   218  			},
   219  			FileInfo: &FileInfo{
   220  				Path:      "/path/to/table1.csv",
   221  				Delimiter: ',',
   222  			},
   223  		},
   224  		Result: GenerateViewMap([]*View{
   225  			{
   226  				Header: NewHeader("table1", []string{"column1", "column2"}),
   227  				RecordSet: []Record{
   228  					NewRecord([]value.Primary{
   229  						value.NewString("1"),
   230  						value.NewString("str1"),
   231  					}),
   232  					NewRecord([]value.Primary{
   233  						value.NewString("2"),
   234  						value.NewString("str2"),
   235  					}),
   236  				},
   237  				FileInfo: &FileInfo{
   238  					Path:      "/path/to/table1.csv",
   239  					Delimiter: ',',
   240  				},
   241  			},
   242  		}),
   243  	},
   244  }
   245  
   246  func TestViewMap_Set(t *testing.T) {
   247  	viewMap := NewViewMap()
   248  
   249  	for _, v := range viewMapSetTests {
   250  		viewMap.Set(v.SetView)
   251  		if !SyncMapEqual(viewMap, v.Result) {
   252  			t.Errorf("%s: map = %v, want %v", v.Name, viewMap, v.Result)
   253  		}
   254  	}
   255  }
   256  
   257  var viewMapDisposeTemporaryTable = []struct {
   258  	Name   string
   259  	Table  parser.Identifier
   260  	Result ViewMap
   261  	OK     bool
   262  }{
   263  	{
   264  		Name:  "ViewMap DisposeTemporaryTable",
   265  		Table: parser.Identifier{Literal: "/path/to/table1.csv"},
   266  		Result: GenerateViewMap([]*View{
   267  			{
   268  				Header: NewHeader("table1", []string{"column1", "column2"}),
   269  				RecordSet: []Record{
   270  					NewRecord([]value.Primary{
   271  						value.NewString("1"),
   272  						value.NewString("str1"),
   273  					}),
   274  					NewRecord([]value.Primary{
   275  						value.NewString("2"),
   276  						value.NewString("str2"),
   277  					}),
   278  				},
   279  				FileInfo: &FileInfo{
   280  					Path:      "/path/to/table2.csv",
   281  					Delimiter: ',',
   282  				},
   283  			},
   284  		}),
   285  		OK: true,
   286  	},
   287  	{
   288  		Name:  "ViewMap DisposeTemporaryTable Not Temporary Table",
   289  		Table: parser.Identifier{Literal: "/path/to/table2.csv"},
   290  		OK:    false,
   291  	},
   292  	{
   293  		Name:  "ViewMap DisposeTemporaryTable Undeclared Error",
   294  		Table: parser.Identifier{Literal: "/path/to/undef.csv"},
   295  		OK:    false,
   296  	},
   297  }
   298  
   299  func TestViewMap_DisposeTemporaryTable(t *testing.T) {
   300  	viewMap := GenerateViewMap([]*View{
   301  		{
   302  			Header: NewHeader("table1", []string{"column1", "column2"}),
   303  			RecordSet: []Record{
   304  				NewRecord([]value.Primary{
   305  					value.NewString("1"),
   306  					value.NewString("str1"),
   307  				}),
   308  				NewRecord([]value.Primary{
   309  					value.NewString("2"),
   310  					value.NewString("str2"),
   311  				}),
   312  			},
   313  			FileInfo: &FileInfo{
   314  				Path:      "/path/to/table1.csv",
   315  				Delimiter: ',',
   316  				ViewType:  ViewTypeTemporaryTable,
   317  			},
   318  		},
   319  		{
   320  			Header: NewHeader("table1", []string{"column1", "column2"}),
   321  			RecordSet: []Record{
   322  				NewRecord([]value.Primary{
   323  					value.NewString("1"),
   324  					value.NewString("str1"),
   325  				}),
   326  				NewRecord([]value.Primary{
   327  					value.NewString("2"),
   328  					value.NewString("str2"),
   329  				}),
   330  			},
   331  			FileInfo: &FileInfo{
   332  				Path:      "/path/to/table2.csv",
   333  				Delimiter: ',',
   334  			},
   335  		},
   336  	})
   337  
   338  	for _, v := range viewMapDisposeTemporaryTable {
   339  		ok := viewMap.DisposeTemporaryTable(v.Table)
   340  		if ok != v.OK {
   341  			t.Errorf("%s: result = %t, want %t", v.Name, ok, v.OK)
   342  		}
   343  		if ok && v.OK && !SyncMapEqual(viewMap, v.Result) {
   344  			t.Errorf("%s: map = %v, want %v", v.Name, viewMap, v.Result)
   345  		}
   346  	}
   347  }
   348  
   349  func TestViewMap_Clear(t *testing.T) {
   350  	viewMap := GenerateViewMap([]*View{
   351  		{
   352  			Header: NewHeader("table1", []string{"column1", "column2"}),
   353  			RecordSet: []Record{
   354  				NewRecord([]value.Primary{
   355  					value.NewString("1"),
   356  					value.NewString("str1"),
   357  				}),
   358  				NewRecord([]value.Primary{
   359  					value.NewString("2"),
   360  					value.NewString("str2"),
   361  				}),
   362  			},
   363  			FileInfo: &FileInfo{
   364  				Path:      "/path/to/table1.csv",
   365  				Delimiter: ',',
   366  				ViewType:  ViewTypeTemporaryTable,
   367  			},
   368  		},
   369  		{
   370  			Header: NewHeader("table1", []string{"column1", "column2"}),
   371  			RecordSet: []Record{
   372  				NewRecord([]value.Primary{
   373  					value.NewString("1"),
   374  					value.NewString("str1"),
   375  				}),
   376  				NewRecord([]value.Primary{
   377  					value.NewString("2"),
   378  					value.NewString("str2"),
   379  				}),
   380  			},
   381  			FileInfo: &FileInfo{
   382  				Path:      "/path/to/table2.csv",
   383  				Delimiter: ',',
   384  			},
   385  		},
   386  	})
   387  
   388  	expect := NewViewMap()
   389  
   390  	_ = viewMap.Clean(TestTx.FileContainer)
   391  	if !SyncMapEqual(viewMap, expect) {
   392  		t.Errorf("result = %v, want %v", viewMap, expect)
   393  	}
   394  }
   395  
   396  var viewMapGetWithInternalIdBench = generateViewMapGetWithInternalIdBenchViewMap()
   397  
   398  func generateViewMapGetWithInternalIdBenchViewMap() ViewMap {
   399  	m := GenerateViewMap([]*View{{
   400  		Header: NewHeader("bench_view", []string{"c1", "c2", "c3", "c4"}),
   401  		FileInfo: &FileInfo{
   402  			Path: "bench_view",
   403  		},
   404  	}})
   405  	view, _ := m.Load("BENCH_VIEW")
   406  	view.RecordSet = make(RecordSet, 10000)
   407  	for i := 0; i < 10000; i++ {
   408  		view.RecordSet[i] = NewRecord([]value.Primary{
   409  			value.NewInteger(1),
   410  			value.NewInteger(2),
   411  			value.NewInteger(3),
   412  			value.NewInteger(4),
   413  		})
   414  	}
   415  	return m
   416  }
   417  
   418  func BenchmarkViewMap_GetWithInternalId(b *testing.B) {
   419  	for i := 0; i < b.N; i++ {
   420  		_, _ = viewMapGetWithInternalIdBench.GetWithInternalId(context.Background(), strings.ToUpper("BENCH_VIEW"), TestTx.Flags)
   421  	}
   422  }