| 
									
										
										
										
											2025-05-17 01:11:04 +00:00
										 |  |  | package cmdpacks_test | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2025-10-24 06:48:27 +00:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							| 
									
										
										
										
											2025-05-26 12:04:23 +00:00
										 |  |  | 	"lmika.dev/cmd/dynamo-browse/internal/common/ui/commandctrl/cmdpacks" | 
					
						
							|  |  |  | 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models" | 
					
						
							| 
									
										
										
										
											2025-05-17 01:11:04 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestModRS_New(t *testing.T) { | 
					
						
							|  |  |  | 	svc := newService(t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rsProxy, err := svc.CommandController.ExecuteAndWait(t.Context(), `rs:new`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2025-05-19 12:14:22 +00:00
										 |  |  | 	assert.IsType(t, rsProxy, cmdpacks.SimpleProxy[*models.ResultSet]{}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestModRS_NextPage(t *testing.T) { | 
					
						
							|  |  |  | 	t.Run("multiple pages", func(t *testing.T) { | 
					
						
							|  |  |  | 		svc := newService(t, withDataGenerator(largeTestData), withTable("large-table"), withDefaultLimit(20)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		hasNextPage, err := svc.CommandController.ExecuteAndWait(t.Context(), `@resultset.HasNextPage`) | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.True(t, hasNextPage.(bool)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Page 2
 | 
					
						
							|  |  |  | 		rsProxy, err := svc.CommandController.ExecuteAndWait(t.Context(), `rs:next-page @resultset`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.IsType(t, cmdpacks.SimpleProxy[*models.ResultSet]{}, rsProxy) | 
					
						
							|  |  |  | 		assert.Equal(t, 20, len(rsProxy.(cmdpacks.SimpleProxy[*models.ResultSet]).ProxyValue().Items())) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		hasNextPage, err = svc.CommandController.ExecuteAndWait(t.Context(), `(rs:next-page @resultset).HasNextPage`) | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.True(t, hasNextPage.(bool)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Page 3
 | 
					
						
							|  |  |  | 		rsProxy, err = svc.CommandController.ExecuteAndWait(t.Context(), `rs:next-page @resultset | rs:next-page`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.IsType(t, cmdpacks.SimpleProxy[*models.ResultSet]{}, rsProxy) | 
					
						
							|  |  |  | 		assert.Equal(t, 10, len(rsProxy.(cmdpacks.SimpleProxy[*models.ResultSet]).ProxyValue().Items())) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		hasNextPage, err = svc.CommandController.ExecuteAndWait(t.Context(), `(rs:next-page @resultset | rs:next-page).HasNextPage`) | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.False(t, hasNextPage.(bool)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Last page
 | 
					
						
							|  |  |  | 		rsProxy, err = svc.CommandController.ExecuteAndWait(t.Context(), `rs:next-page (rs:next-page @resultset | rs:next-page)`) | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Nil(t, rsProxy) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("only one page", func(t *testing.T) { | 
					
						
							|  |  |  | 		svc := newService(t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		hasNextPage, err := svc.CommandController.ExecuteAndWait(t.Context(), `@resultset.HasNextPage`) | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.False(t, hasNextPage.(bool)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		rsProxy, err := svc.CommandController.ExecuteAndWait(t.Context(), `rs:next-page @resultset`) | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Nil(t, rsProxy) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestModRS_Union(t *testing.T) { | 
					
						
							|  |  |  | 	svc := newService(t, withDefaultLimit(2)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rsProxy, err := svc.CommandController.ExecuteAndWait(t.Context(), ` | 
					
						
							| 
									
										
										
										
											2025-10-24 06:48:27 +00:00
										 |  |  | 		mr = rs:union @resultset (rs:next-page @resultset) | 
					
						
							| 
									
										
										
										
											2025-05-19 12:14:22 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		assert (eq (len $mr.Items) 3) "expected len == 3" | 
					
						
							|  |  |  | 		assert (eq $mr.Items.(0).pk "abc") "expected 0.pk" | 
					
						
							|  |  |  | 		assert (eq $mr.Items.(0).sk "111") "expected 0.sk" | 
					
						
							|  |  |  | 		assert (eq $mr.Items.(1).pk "abc") "expected 1.pk" | 
					
						
							|  |  |  | 		assert (eq $mr.Items.(1).sk "222") "expected 1.sk" | 
					
						
							|  |  |  | 		assert (eq $mr.Items.(2).pk "bbb") "expected 2.pk" | 
					
						
							|  |  |  | 		assert (eq $mr.Items.(2).sk "131") "expected 2.sk" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$mr | 
					
						
							|  |  |  | 	`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert.NoError(t, err) | 
					
						
							|  |  |  | 	assert.IsType(t, cmdpacks.SimpleProxy[*models.ResultSet]{}, rsProxy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rs := rsProxy.(cmdpacks.SimpleProxy[*models.ResultSet]).ProxyValue() | 
					
						
							|  |  |  | 	assert.Equal(t, 3, len(rs.Items())) | 
					
						
							| 
									
										
										
										
											2025-05-17 01:11:04 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestModRS_Query(t *testing.T) { | 
					
						
							|  |  |  | 	tests := []struct { | 
					
						
							|  |  |  | 		descr    string | 
					
						
							|  |  |  | 		cmd      string | 
					
						
							|  |  |  | 		wantRows []int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr:    "query with pk 1", | 
					
						
							|  |  |  | 			cmd:      `rs:query 'pk="abc"' -table service-test-data`, | 
					
						
							|  |  |  | 			wantRows: []int{0, 1}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr:    "query with pk 2", | 
					
						
							|  |  |  | 			cmd:      `rs:query 'pk="bbb"' -table service-test-data`, | 
					
						
							|  |  |  | 			wantRows: []int{2}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr:    "query with sk 1", | 
					
						
							|  |  |  | 			cmd:      `rs:query 'sk="222"' -table service-test-data`, | 
					
						
							|  |  |  | 			wantRows: []int{1}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr:    "query with args 1", | 
					
						
							|  |  |  | 			cmd:      `rs:query 'pk=$v' [v:'abc'] -table service-test-data`, | 
					
						
							|  |  |  | 			wantRows: []int{0, 1}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr:    "query with args 2", | 
					
						
							|  |  |  | 			cmd:      `rs:query ':k=$v' [k:'pk' v:'abc'] -table service-test-data`, | 
					
						
							|  |  |  | 			wantRows: []int{0, 1}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr:    "query with args 3", | 
					
						
							|  |  |  | 			cmd:      `rs:query ':k=$v' [k:'beta' v:1231] -table service-test-data`, | 
					
						
							|  |  |  | 			wantRows: []int{1}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr:    "query with args with no table set", | 
					
						
							|  |  |  | 			cmd:      `rs:query ':k=$v' [k:'beta' v:1231]`, | 
					
						
							|  |  |  | 			wantRows: []int{1}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.descr, func(t *testing.T) { | 
					
						
							|  |  |  | 			svc := newService(t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			res, err := svc.CommandController.ExecuteAndWait(t.Context(), tt.cmd) | 
					
						
							|  |  |  | 			assert.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-19 12:14:22 +00:00
										 |  |  | 			rs := res.(cmdpacks.SimpleProxy[*models.ResultSet]).ProxyValue() | 
					
						
							| 
									
										
										
										
											2025-05-17 01:11:04 +00:00
										 |  |  | 			assert.Len(t, rs.Items(), len(tt.wantRows)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for i, rowIndex := range tt.wantRows { | 
					
						
							| 
									
										
										
										
											2025-05-19 12:14:22 +00:00
										 |  |  | 				for key, want := range svc.testData[0].Data[rowIndex] { | 
					
						
							| 
									
										
										
										
											2025-05-17 01:11:04 +00:00
										 |  |  | 					have, ok := rs.Items()[i].AttributeValueAsString(key) | 
					
						
							|  |  |  | 					assert.True(t, ok) | 
					
						
							|  |  |  | 					assert.Equal(t, fmt.Sprint(want), have) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-10-24 06:48:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestModRS_First(t *testing.T) { | 
					
						
							|  |  |  | 	tests := []struct { | 
					
						
							|  |  |  | 		descr string | 
					
						
							|  |  |  | 		cmd   string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			descr: "returns the first item in sorted order", | 
					
						
							|  |  |  | 			cmd: ` | 
					
						
							|  |  |  | 				rs = rs:query 'pk="abc"' -table service-test-data | 
					
						
							|  |  |  | 				assert (eq $rs.First.pk "abc") "expected First.pk == abc" | 
					
						
							|  |  |  | 				assert (eq $rs.First.sk "111") "expected First.sk == 111" | 
					
						
							|  |  |  | 			`, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			descr: "returns the first item in single item", | 
					
						
							|  |  |  | 			cmd: ` | 
					
						
							|  |  |  | 				rs = rs:query 'pk="abc" and sk="222"' -table service-test-data | 
					
						
							|  |  |  | 				assert (eq $rs.First.pk "abc") "expected First.pk == abc" | 
					
						
							|  |  |  | 				assert (eq $rs.First.sk "222") "expected First.sk == 222" | 
					
						
							|  |  |  | 				assert (eq $rs.First.beta 1231) "expected First.beta == 1231" | 
					
						
							|  |  |  | 			`, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			descr: "returns the first item in empty result", | 
					
						
							|  |  |  | 			cmd: ` | 
					
						
							|  |  |  | 				rs = rs:query 'pk="zzz"' -table service-test-data | 
					
						
							|  |  |  | 				assert (eq $rs.First ()) "expected First to be nil" | 
					
						
							|  |  |  | 			`, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.descr, func(t *testing.T) { | 
					
						
							|  |  |  | 			svc := newService(t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			_, err := svc.CommandController.ExecuteAndWait(t.Context(), tt.cmd) | 
					
						
							|  |  |  | 			assert.NoError(t, err) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |