From c1f2a28ac155cde8654c4a9051e5d3924dec068c Mon Sep 17 00:00:00 2001 From: Sacha Ligthert Date: Wed, 29 Jan 2025 17:45:08 +0100 Subject: [PATCH] Provided tests for functions that can be tested (Closes #20). --- README.md | 2 +- export/Export_test.go | 90 ++++++++++++++++++++++++++++++ export/renderFlat_test.go | 39 +++++++++++++ export/renderHumanReadable_test.go | 45 +++++++++++++++ export/renderJSON_test.go | 54 ++++++++++++++++++ flags/validChar_test.go | 39 +++++++++++++ solver/LoadBlocks_test.go | 40 +++++++++++++ solver/PopulateBlocks_test.go | 90 ++++++++++++++++++++++++++++++ solver/calcAVG_test.go | 33 +++++++++++ solver/findBlocks_test.go | 53 ++++++++++++++++++ solver/setWorkload_test.go | 72 ++++++++++++++++++++++++ solver/splitWorkload_test.go | 51 +++++++++++++++++ solver/validateCombination_test.go | 16 ++++++ solver/validator_test.go | 53 ++++++++++++++++++ 14 files changed, 676 insertions(+), 1 deletion(-) create mode 100644 export/Export_test.go create mode 100644 export/renderFlat_test.go create mode 100644 export/renderHumanReadable_test.go create mode 100644 export/renderJSON_test.go create mode 100644 flags/validChar_test.go create mode 100644 solver/LoadBlocks_test.go create mode 100644 solver/PopulateBlocks_test.go create mode 100644 solver/calcAVG_test.go create mode 100644 solver/findBlocks_test.go create mode 100644 solver/setWorkload_test.go create mode 100644 solver/splitWorkload_test.go create mode 100644 solver/validateCombination_test.go create mode 100644 solver/validator_test.go diff --git a/README.md b/README.md index d0b033e..c0ccb0d 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ For a long running (~1 hours 15 minutes) example: The outpot (of the short running parameters) will look something like this: ``` -./sudoku-funpark -row1 769104802 -row2 154800060 -row3 832700154 -row4 600900328 -row5 045328670 -row6 328670945 -row7 597410280 -row8 006283090 -row9 200590006 +./sudoku-funpark -row1 769104802 -row2 154800060 -row3 832700154 -row4 600900328 -row5 045328670 -row6 328670945 -row7 597410280 -row8 006283090 -row9 200590006 Loading blocks... Done! (38.957376ms) Populating blocks... Done! (92.087174ms) Number of (potential) solutions: 26542080 diff --git a/export/Export_test.go b/export/Export_test.go new file mode 100644 index 0000000..5d1ab70 --- /dev/null +++ b/export/Export_test.go @@ -0,0 +1,90 @@ +package export + +import ( + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// This function will test the Export function. +// Starts off by creating all the structs and intefaces needed. +// Set all the needed values. +// Execute the Export function. +// Check if the output is a string. +// Check if the output for "human" "flat" and "json" are valid. +func TestExport(t *testing.T) { + + // Create a new Export struct. + export := Export{} + + // Create a new outputter struct. + outp := outputter.Outputter{} + + // Set output type to "short". + outp.OutputType = "short" + + // Create a new Controller struct and set the outputter. + controller := controller.Controller{Outputter: &outp} + + // Set the Controller in the Export struct. + export.Controller = &controller + + // Populate the Solutions slice. + controller.Solutions = append(controller.Solutions, []string{"123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789"}) + + // Set output type to "human". + controller.Output = "human" + + // Execute the Export function. + render := export.Export() + + // Check if the output is a string and not empty. + if render == "" { + t.Error("Expected a non-empty string, string was empty") + } + + // Set the expected variable. + expected := "\nSolution #1:\n╔═══════════╗\n║123│456│789╢\n║987│654│321╢\n║123│456│789╢\n╟───┼───┼───╢\n║987│654│321╢\n║123│456│789╢\n║987│654│321╢\n╟───┼───┼───╢\n║123│456│789╢\n║987│654│321╢\n║123│456│789╢\n╚═══════════╝\n" + + // Check if the output is the same as the expected variable. + if render != expected { + t.Error("Expected a ", expected, ", got", render) + } + + // Set output type to "flat". + controller.Output = "flat" + + // Execute the Export function. + render = export.Export() + + // Check if the output for "flat" is non-empty. + if render == "" { + t.Error("Expected a non-empty string, string was empty") + } + + expected = "\nSolution #1:\n[123456789 987654321 123456789 987654321 123456789 987654321 123456789 987654321 123456789]\n" + + if render != expected { + t.Error("Expected a ", expected, ", got", render) + } + + // Set output type to "json". + controller.Output = "json" + + // Execute the Export function. + render = export.Export() + + // Check if the output for "json" is valid. + if render == "" { + t.Error("Expected a non-empty string, got empty string") + } + + // Set the expected variable. + expected = "[{\"order\":0,\"row1\":\"123456789\",\"row2\":\"987654321\",\"row3\":\"123456789\",\"row4\":\"987654321\",\"row5\":\"123456789\",\"row6\":\"987654321\",\"row7\":\"123456789\",\"row8\":\"987654321\",\"row9\":\"123456789\"}]" + + // Check if what is rendered is the same as the expected variable. + if render != expected { + t.Error("Expected a ", expected, ", got", render) + } +} diff --git a/export/renderFlat_test.go b/export/renderFlat_test.go new file mode 100644 index 0000000..dd4098a --- /dev/null +++ b/export/renderFlat_test.go @@ -0,0 +1,39 @@ +package export + +import ( + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// This function will test the renderFlat function. +// Then it will execute the renderFlat function. +// Check if the output is a string. +func TestRenderFlat(t *testing.T) { + + // Create a new Export struct. + export := Export{} + + // Create a new Controller struct. + // Set output type to "human". + outp := outputter.Outputter{} + outp.OutputType = "short" + controller := controller.Controller{Outputter: &outp} + export.Controller = &controller + controller.Solutions = append(controller.Solutions, []string{"123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789"}) + + // Execute the renderFlat function. + render := export.renderFlat() + + // Check if the output is a string and not empty. + if render == "" { + t.Error("Expected a non-empty string, got", render) + } + + // Check if the output is a string. + if render != "\nSolution #1:\n[123456789 987654321 123456789 987654321 123456789 987654321 123456789 987654321 123456789]\n" { + t.Error("Expected a string, got", render) + } + +} diff --git a/export/renderHumanReadable_test.go b/export/renderHumanReadable_test.go new file mode 100644 index 0000000..676d44f --- /dev/null +++ b/export/renderHumanReadable_test.go @@ -0,0 +1,45 @@ +package export + +import ( + "strings" + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// This function will test the renderHumanReadable function. +// Starts off by creating a new Export struct. +// Creates a new Controller struct. +// Adds a solution to the Controller struct. +// Then it will execute the renderHumanReadable function. +// Check if the output is a string. +func TestRenderHumanReadable(t *testing.T) { + + // Create a new Export struct. + export := Export{} + + // Create a new Controller struct. + // Set output type to "human". + outp := outputter.Outputter{} + outp.OutputType = "short" + controller := controller.Controller{Outputter: &outp} + export.Controller = &controller + controller.Solutions = append(controller.Solutions, []string{"123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789"}) + + // Execute the renderHumanReadable function. + render := export.renderHumanReadable() + + expected := "\nSolution #1:\n╔═══════════╗\n║123│456│789╢\n║987│654│321╢\n║123│456│789╢\n╟───┼───┼───╢\n║987│654│321╢\n║123│456│789╢\n║987│654│321╢\n╟───┼───┼───╢\n║123│456│789╢\n║987│654│321╢\n║123│456│789╢\n╚═══════════╝\n" + + // Check if the output is a string and not empty. + if render == "" { + t.Error("Expected a non-empty string, got", render) + } + + // Check if the output is a string. + if strings.TrimSpace(render) != strings.TrimSpace(expected) { + t.Error("Expected a string, got", render) + } + +} diff --git a/export/renderJSON_test.go b/export/renderJSON_test.go new file mode 100644 index 0000000..9f53fc9 --- /dev/null +++ b/export/renderJSON_test.go @@ -0,0 +1,54 @@ +package export + +import ( + "encoding/json" + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// This function will test the renderJSON function. +// Starts off by creating a new Export struct. +// Creates a new Controller struct. +// Adds a solution to the Controller struct. +// Then it will execute the renderJSON function. +// Check if the output is a JSON string. +func TestRenderJSON(t *testing.T) { + + // Create a new Export struct. + export := Export{} + outp := outputter.Outputter{} + outp.OutputType = "short" + export.Controller = &controller.Controller{Outputter: &outp} + + // Create a new Controller struct. + controller := controller.Controller{} + controller.Solutions = append(controller.Solutions, []string{"123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789", "987654321", "123456789"}) + + // Add a solution to the Controller struct. + export.Controller = &controller + + // Execute the renderJSON function. + render := export.renderJSON() + + // Check if the output is a JSON string and not empty. + if render == "" { + t.Error("Expected a non-empty JSON string, got", render) + } + + // Check if the output is a JSON string.\ + if render != "[{\"order\":0,\"row1\":\"123456789\",\"row2\":\"987654321\",\"row3\":\"123456789\",\"row4\":\"987654321\",\"row5\":\"123456789\",\"row6\":\"987654321\",\"row7\":\"123456789\",\"row8\":\"987654321\",\"row9\":\"123456789\"}]" { + t.Error("Expected a JSON string, got", render) + } + + // Check if the outpt is a valid JSON string. + // Check using the json.Unmarshal function. + // If the output is not a valid JSON string, the Unmarshal function will throw an error. + var result []map[string]interface{} + err := json.Unmarshal([]byte(render), &result) + if err != nil { + t.Error("Expected a valid JSON string, got", render) + } + +} diff --git a/flags/validChar_test.go b/flags/validChar_test.go new file mode 100644 index 0000000..78ffa01 --- /dev/null +++ b/flags/validChar_test.go @@ -0,0 +1,39 @@ +package flags + +import "testing" + +func TestValidChar(t *testing.T) { + tests := []struct { + name string + char rune + valid bool + }{ + { + name: "Valid char", + char: '1', + valid: true, + }, + { + name: "Invalid char", + char: 'a', + valid: false, + }, + { + name: "Valid char but not relevant", + char: '0', + valid: true, + }, + } + + flags := Flags{} + + // Run tests + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := flags.validChar(tt.char); got != tt.valid { + t.Errorf("validChar() = %v, want %v", got, tt.valid) + } + }) + } + +} diff --git a/solver/LoadBlocks_test.go b/solver/LoadBlocks_test.go new file mode 100644 index 0000000..859b562 --- /dev/null +++ b/solver/LoadBlocks_test.go @@ -0,0 +1,40 @@ +package solver + +import ( + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// This function will test the loadBlocks function. +// Starts off by creating a new Solver struct. +// Then it will execute the loadBlocks function. +// Check if there are 9! blocks loaded. +// Check if the first block is "123456789". +// check if the last block is "987654321". +func TestLoadBlocks(t *testing.T) { + + // Do all the necesarry steps to initialize the solver. + solver := Solver{} + outp := outputter.Outputter{} + outp.OutputType = "short" + solver.Outp = &outp + controller := controller.Controller{} + solver.Controller = &controller + solver.LoadBlocks() + + // Check if there are 9! blocks loaded. + if len(solver.Controller.Blocks) != 362880 { + t.Error("Expected 362880, got", len(solver.Controller.Blocks)) + } + // Check if the first block is "123456789". + if solver.Controller.Blocks[0] != "123456789" { + t.Error("Expected 123456789, got", solver.Controller.Blocks[0]) + } + // Check if the last block is "987654321". + if solver.Controller.Blocks[362879] != "987654321" { + t.Error("Expected 987654321, got", solver.Controller.Blocks[362879]) + } + +} diff --git a/solver/PopulateBlocks_test.go b/solver/PopulateBlocks_test.go new file mode 100644 index 0000000..404aad5 --- /dev/null +++ b/solver/PopulateBlocks_test.go @@ -0,0 +1,90 @@ +package solver + +import ( + "slices" + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// This functions tests the PopulateBlocks function. +// It does this by creating a small set of rows and then +// calling the PopulateBlocks function. It then checks +// if the number of blocks is as expected. +func TestPopulateBlocks(t *testing.T) { + // Do all the necesarry steps to initialize the solver. + solver := Solver{} + outp := outputter.Outputter{} + outp.OutputType = "short" + solver.Outp = &outp + controller := controller.Controller{} + solver.Controller = &controller + solver.LoadBlocks() + + // Create a set of rows + // Using the following values: [769154832 154832769 832769154 671945328 945328671 328671945 597416283 416283597 283597416] + solver.Controller.Row1 = "769154800" + solver.Controller.Row2 = "154832700" + solver.Controller.Row3 = "832769100" + solver.Controller.Row4 = "671945300" + solver.Controller.Row5 = "945328600" + solver.Controller.Row6 = "328671900" + solver.Controller.Row7 = "597416200" + solver.Controller.Row8 = "416283500" + solver.Controller.Row9 = "283597400" + + // Call the PopulateBlocks function + solver.PopulateBlocks() + + // Check if the number of blocks is as expected + if solver.Iter != 512 { + t.Errorf("Expected 19683 blocks, got %d", solver.Iter) + } + + // Check if solver.row1s is as expected + if slices.Compare(solver.row1s, []string{"769154823", "769154832"}) != 0 { + t.Errorf("Expected [769154832, 769154823], got %s", solver.row1s) + } + + // check if solver.row2s is as expected + if slices.Compare(solver.row2s, []string{"154832769", "154832796"}) != 0 { + t.Errorf("Expected [154832769, 154832796], got %s", solver.row2s) + } + + // check if solver.row3s is as expected + if slices.Compare(solver.row3s, []string{"832769145", "832769154"}) != 0 { + t.Errorf("Expected [832769154, 832769145], got %s", solver.row3s) + } + + // check if solver.row4s is as expected + if slices.Compare(solver.row4s, []string{"671945328", "671945382"}) != 0 { + t.Errorf("Expected [671945328, 671945382], got %s", solver.row4s) + } + + // check if solver.row5s is as expected + if slices.Compare(solver.row5s, []string{"945328617", "945328671"}) != 0 { + t.Errorf("Expected [945328617, 945328671], got %s", solver.row5s) + } + + // check if solver.row6s is as expected + if slices.Compare(solver.row6s, []string{"328671945", "328671954"}) != 0 { + t.Errorf("Expected [328671945, 328671954], got %s", solver.row6s) + } + + // check if solver.row7s is as expected + if slices.Compare(solver.row7s, []string{"597416238", "597416283"}) != 0 { + t.Errorf("Expected [597416238, 597416283], got %s", solver.row7s) + } + + // check if solver.row8s is as expected + if slices.Compare(solver.row8s, []string{"416283579", "416283597"}) != 0 { + t.Errorf("Expected [416283579, 416283597], got %s", solver.row8s) + } + + // check if solver.row9s is as expected + if slices.Compare(solver.row9s, []string{"283597416", "283597461"}) != 0 { + t.Errorf("Expected [283597416, 283597461], got %s", solver.row9s) + } + +} diff --git a/solver/calcAVG_test.go b/solver/calcAVG_test.go new file mode 100644 index 0000000..f38f133 --- /dev/null +++ b/solver/calcAVG_test.go @@ -0,0 +1,33 @@ +package solver + +import ( + "testing" +) + +// Test the calcAVG function. +func TestCalcAVG(t *testing.T) { + + // Create a new Solver struct. + solver := Solver{} + // Populate the solver.rates[] slice with some values and check if the average is calculated correctly. + solver.rates = []uint64{1, 2, 3, 4, 5} + if solver.calcAVG() != 3 { + t.Error("Expected 3, got", solver.calcAVG()) + } + // Populate the solver.Rate[] slice with some values and check if the average is calculated correctly. + solver.rates = []uint64{1, 2, 3, 4, 5, 6} + if solver.calcAVG() != 3 { + t.Error("Expected 3, got", solver.calcAVG()) + } + // Populate the solver.Rate[] slice with some values and check if the average is calculated correctly. + solver.rates = []uint64{1, 2, 3, 4, 5, 6, 7} + if solver.calcAVG() != 4 { + t.Error("Expected 4, got", solver.calcAVG()) + } + // Populate the solver.Rate[] slice with some values and check if the average is calculated correctly. + solver.rates = []uint64{1, 2, 3, 4, 5, 6, 7, 8} + if solver.calcAVG() != 4 { + t.Error("Expected 4, got", solver.calcAVG()) + } + +} diff --git a/solver/findBlocks_test.go b/solver/findBlocks_test.go new file mode 100644 index 0000000..0cc4f89 --- /dev/null +++ b/solver/findBlocks_test.go @@ -0,0 +1,53 @@ +package solver + +import ( + "slices" + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// TestfindBlocks tests the findBlocks function. +// It defines the solver struct +// and calls the findBlocks function with a row and a slice of rows. +// It then checks if the slice of rows is as expected. +func TestFindBlocks(t *testing.T) { + + // Create a new Solver struct. + solver := Solver{} + + // Create outputter struct. + outp := outputter.Outputter{} + + // Set the output type to human. + outp.OutputType = "human" + + // Set the outputter of the solver to the outputter. + solver.Outp = &outp + + // Create a controller struct. + controller := controller.Controller{} + + // Set the controller of the solver to the controller. + solver.Controller = &controller + + // Execute the loadBlocks function. + solver.LoadBlocks() + + // Provide controller.row1 with a value. + // This is the row that will be used in the findBlocks function. + controller.Row1 = "769104802" + + // Call the findBlocks function with the row and the slice of rows. + solver.findBlocks(&controller.Row1, &solver.row1s) + + // A slice with the expected results. + expected := []string{"769154832", "769134852"} + + // Check if the slice of rows1 is same as expected variable. + if slices.Equal(solver.row1s, expected) { + t.Errorf("Expected %v, got %v", expected, solver.row1s) + } + +} diff --git a/solver/setWorkload_test.go b/solver/setWorkload_test.go new file mode 100644 index 0000000..838f7db --- /dev/null +++ b/solver/setWorkload_test.go @@ -0,0 +1,72 @@ +package solver + +import ( + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// Function to test the setWorkload function. +func TestSetWorkload(t *testing.T) { + // Create a new Solver struct. + solver := Solver{} + + // Create outputter struct. + outp := outputter.Outputter{} + + // Set the output type to human. + outp.OutputType = "short" + + // Set the outputter of the solver to the outputter. + solver.Outp = &outp + + // Create a controller struct. + controller := controller.Controller{} + + // Set the controller of the solver to the controller. + solver.Controller = &controller + + // Execute the loadBlocks function. + solver.LoadBlocks() + + // Provide controller.row1 with a value. + // This is the row that will be used in the findBlocks function. + controller.Row1 = "769104802" + + // Fill the other rows with values. + solver.row2s = []string{"769104802"} + solver.row3s = []string{"769104802"} + solver.row4s = []string{"769104802"} + solver.row5s = []string{"769104802"} + solver.row6s = []string{"769104802"} + solver.row7s = []string{"769104802"} + solver.row8s = []string{"769104802"} + solver.row9s = []string{"769104802"} + + // Call the findBlocks function with the row and the slice of rows. + solver.findBlocks(&controller.Row1, &solver.row1s) + + // Divide the work between two agents. + solver.Controller.Split = 2 + + // Set the part of the workload that the first agent will do. + solver.Controller.Part = 1 + + // Call the splitWorkload function. + agents := solver.splitWorkload() + + // Run the setWorkload function. + solver.setWorkload(agents) + + // Check if the solver.row1s slice is as expected. + if len(solver.row1s) != 1 { + t.Errorf("Expected 1, got %v", len(solver.row1s)) + } + + // Check if the solver.Iter value is as expected. + if solver.Iter != 1 { + t.Errorf("Expected 9, got %v", solver.Iter) + } + +} diff --git a/solver/splitWorkload_test.go b/solver/splitWorkload_test.go new file mode 100644 index 0000000..675ee39 --- /dev/null +++ b/solver/splitWorkload_test.go @@ -0,0 +1,51 @@ +package solver + +import ( + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// Test the splitWorkload function. +func TestSplitWorkload(t *testing.T) { + // Create a new Solver struct. + solver := Solver{} + + // Create outputter struct. + outp := outputter.Outputter{} + + // Set the output type to human. + outp.OutputType = "human" + + // Set the outputter of the solver to the outputter. + solver.Outp = &outp + + // Create a controller struct. + controller := controller.Controller{} + + // Set the controller of the solver to the controller. + solver.Controller = &controller + + // Execute the loadBlocks function. + solver.LoadBlocks() + + // Provide controller.row1 with a value. + // This is the row that will be used in the findBlocks function. + controller.Row1 = "769104802" + + // Call the findBlocks function with the row and the slice of rows. + solver.findBlocks(&controller.Row1, &solver.row1s) + + // Divide the work between two agents. + solver.Controller.Split = 2 + + // Call the splitWorkload function. + agents := solver.splitWorkload() + + // Check if the agents slice is as expected. + if agents[0] != 1 || agents[1] != 1 { + t.Errorf("Expected [1, 1], got %v", agents) + } + +} diff --git a/solver/validateCombination_test.go b/solver/validateCombination_test.go new file mode 100644 index 0000000..2cfcb7b --- /dev/null +++ b/solver/validateCombination_test.go @@ -0,0 +1,16 @@ +package solver + +import ( + "testing" +) + +// TestValidateCombination tests the validateCombination function. +func TestValidateCombination(t *testing.T) { + // Create a new solver + solver := Solver{} + + // Test the validateCombination function + if !solver.validateCombination("769154832", "154832769", "832769154", "671945328", "945328671", "328671945", "597416283", "416283597", "283597416") { + t.Error("validateCombination failed") + } +} diff --git a/solver/validator_test.go b/solver/validator_test.go new file mode 100644 index 0000000..0b456c0 --- /dev/null +++ b/solver/validator_test.go @@ -0,0 +1,53 @@ +package solver + +import ( + "testing" + + "gitea.ligthert.net/golang/sudoku-funpark/controller" + "gitea.ligthert.net/golang/sudoku-funpark/outputter" +) + +// This function will test the validator function. +// It will create all the structs, and set required values +// Load the blocks, populate the blocks, and then run the validator +func TestValidator(t *testing.T) { + // Do all the necesarry steps to initialize the solver. + solver := Solver{} + outp := outputter.Outputter{} + outp.OutputType = "short" + solver.Outp = &outp + controller := controller.Controller{} + solver.Controller = &controller + solver.LoadBlocks() + + // Fill the slices of solver.rows with the following values: + // [769154832 154832769 832769154 671945328 945328671 328671945 597416283 416283597 283597416] + solver.row1s = []string{"769154832"} + solver.row2s = []string{"154832769"} + solver.row3s = []string{"832769154"} + solver.row4s = []string{"671945328"} + solver.row5s = []string{"945328671"} + solver.row6s = []string{"328671945"} + solver.row7s = []string{"597416283"} + solver.row8s = []string{"416283597"} + solver.row9s = []string{"283597416"} + + // Set the rows to validate + rows1Index := 0 + rows2Index := 0 + rows3Index := 0 + rows4Index := 0 + rows5Index := 0 + rows6Index := 0 + rows7Index := 0 + rows8Index := 0 + rows9Index := 0 + + // Run the validator + solver.validator(rows1Index, rows2Index, rows3Index, rows4Index, rows5Index, rows6Index, rows7Index, rows8Index, rows9Index) + + // Check the number of solutions + if len(controller.Solutions) != 1 { + t.Errorf("Expected 1 solution, got %d", len(controller.Solutions)) + } +}