123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /**
- * Unit tests for Matrix
- *
- * Copyright 2015, Klaus Post
- * Copyright 2015, Backblaze, Inc. All rights reserved.
- */
- package reedsolomon
- import (
- "testing"
- )
- // TestNewMatrix - Tests validate the result for invalid input and the allocations made by newMatrix method.
- func TestNewMatrix(t *testing.T) {
- testCases := []struct {
- rows int
- columns int
- // flag to indicate whether the test should pass.
- shouldPass bool
- expectedResult matrix
- expectedErr error
- }{
- // Test case - 1.
- // Test case with a negative row size.
- {-1, 10, false, nil, errInvalidRowSize},
- // Test case - 2.
- // Test case with a negative column size.
- {10, -1, false, nil, errInvalidColSize},
- // Test case - 3.
- // Test case with negative value for both row and column size.
- {-1, -1, false, nil, errInvalidRowSize},
- // Test case - 4.
- // Test case with 0 value for row size.
- {0, 10, false, nil, errInvalidRowSize},
- // Test case - 5.
- // Test case with 0 value for column size.
- {-1, 0, false, nil, errInvalidRowSize},
- // Test case - 6.
- // Test case with 0 value for both row and column size.
- {0, 0, false, nil, errInvalidRowSize},
- }
- for i, testCase := range testCases {
- actualResult, actualErr := newMatrix(testCase.rows, testCase.columns)
- if actualErr != nil && testCase.shouldPass {
- t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, actualErr.Error())
- }
- if actualErr == nil && !testCase.shouldPass {
- t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead.", i+1, testCase.expectedErr)
- }
- // Failed as expected, but does it fail for the expected reason.
- if actualErr != nil && !testCase.shouldPass {
- if testCase.expectedErr != actualErr {
- t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead.", i+1, testCase.expectedErr, actualErr)
- }
- }
- // Test passes as expected, but the output values
- // are verified for correctness here.
- if actualErr == nil && testCase.shouldPass {
- if testCase.rows != len(actualResult) {
- // End the tests here if the the size doesn't match number of rows.
- t.Fatalf("Test %d: Expected the size of the row of the new matrix to be `%d`, but instead found `%d`", i+1, testCase.rows, len(actualResult))
- }
- // Iterating over each row and validating the size of the column.
- for j, row := range actualResult {
- // If the row check passes, verify the size of each columns.
- if testCase.columns != len(row) {
- t.Errorf("Test %d: Row %d: Expected the size of the column of the new matrix to be `%d`, but instead found `%d`", i+1, j+1, testCase.columns, len(row))
- }
- }
- }
- }
- }
- // TestMatrixIdentity - validates the method for returning identity matrix of given size.
- func TestMatrixIdentity(t *testing.T) {
- m, err := identityMatrix(3)
- if err != nil {
- t.Fatal(err)
- }
- str := m.String()
- expect := "[[1, 0, 0], [0, 1, 0], [0, 0, 1]]"
- if str != expect {
- t.Fatal(str, "!=", expect)
- }
- }
- // Tests validate the output of matrix multiplication method.
- func TestMatrixMultiply(t *testing.T) {
- m1, err := newMatrixData(
- [][]byte{
- []byte{1, 2},
- []byte{3, 4},
- })
- if err != nil {
- t.Fatal(err)
- }
- m2, err := newMatrixData(
- [][]byte{
- []byte{5, 6},
- []byte{7, 8},
- })
- if err != nil {
- t.Fatal(err)
- }
- actual, err := m1.Multiply(m2)
- if err != nil {
- t.Fatal(err)
- }
- str := actual.String()
- expect := "[[11, 22], [19, 42]]"
- if str != expect {
- t.Fatal(str, "!=", expect)
- }
- }
- // Tests validate the output of the method with computes inverse of matrix.
- func TestMatrixInverse(t *testing.T) {
- testCases := []struct {
- matrixData [][]byte
- // expected inverse matrix.
- expectedResult string
- // flag indicating whether the test should pass.
- shouldPass bool
- expectedErr error
- }{
- // Test case - 1.
- // Test case validating inverse of the input Matrix.
- {
- // input data to construct the matrix.
- [][]byte{
- []byte{56, 23, 98},
- []byte{3, 100, 200},
- []byte{45, 201, 123},
- },
- // expected Inverse matrix.
- "[[175, 133, 33], [130, 13, 245], [112, 35, 126]]",
- // test is expected to pass.
- true,
- nil,
- },
- // Test case - 2.
- // Test case validating inverse of the input Matrix.
- {
- // input data to construct the matrix.
- [][]byte{
- []byte{1, 0, 0, 0, 0},
- []byte{0, 1, 0, 0, 0},
- []byte{0, 0, 0, 1, 0},
- []byte{0, 0, 0, 0, 1},
- []byte{7, 7, 6, 6, 1},
- },
- // expectedInverse matrix.
- "[[1, 0, 0, 0, 0]," +
- " [0, 1, 0, 0, 0]," +
- " [123, 123, 1, 122, 122]," +
- " [0, 0, 1, 0, 0]," +
- " [0, 0, 0, 1, 0]]",
- // test is expected to pass.
- true,
- nil,
- },
- // Test case with a non-square matrix.
- // expected to fail with errNotSquare.
- {
- [][]byte{
- []byte{56, 23},
- []byte{3, 100},
- []byte{45, 201},
- },
- "",
- false,
- errNotSquare,
- },
- // Test case with singular matrix.
- // expected to fail with error errSingular.
- {
- [][]byte{
- []byte{4, 2},
- []byte{12, 6},
- },
- "",
- false,
- errSingular,
- },
- }
- for i, testCase := range testCases {
- m, err := newMatrixData(testCase.matrixData)
- if err != nil {
- t.Fatalf("Test %d: Failed initializing new Matrix : %s", i+1, err)
- }
- actualResult, actualErr := m.Invert()
- if actualErr != nil && testCase.shouldPass {
- t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, actualErr.Error())
- }
- if actualErr == nil && !testCase.shouldPass {
- t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead.", i+1, testCase.expectedErr)
- }
- // Failed as expected, but does it fail for the expected reason.
- if actualErr != nil && !testCase.shouldPass {
- if testCase.expectedErr != actualErr {
- t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead.", i+1, testCase.expectedErr, actualErr)
- }
- }
- // Test passes as expected, but the output values
- // are verified for correctness here.
- if actualErr == nil && testCase.shouldPass {
- if testCase.expectedResult != actualResult.String() {
- t.Errorf("Test %d: The inverse matrix doesn't match the expected result", i+1)
- }
- }
- }
- }
|