github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/pkg/utils/sort_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2021-Present The Jackal Authors
     3  
     4  // Package utils provides generic utility functions.
     5  package utils
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  type TestDependency struct {
    15  	name         string
    16  	dependencies []string
    17  }
    18  
    19  func (t TestDependency) Name() string {
    20  	return t.name
    21  }
    22  
    23  func (t TestDependency) Dependencies() []string {
    24  	return t.dependencies
    25  }
    26  
    27  func TestSortDependencies(t *testing.T) {
    28  	tests := []struct {
    29  		name     string
    30  		data     []TestDependency // input data: a map of nodes to their dependencies
    31  		expected []string         // expected output: a slice of nodes in order of their precedence
    32  		success  bool             // whether the test should succeed or fail
    33  	}{
    34  		{
    35  			name: "simple graph",
    36  			data: []TestDependency{
    37  				{
    38  					name:         "A",
    39  					dependencies: []string{"B", "C"},
    40  				},
    41  				{
    42  					name:         "B",
    43  					dependencies: []string{"C"},
    44  				},
    45  				{
    46  					name: "C",
    47  				},
    48  			},
    49  			// C has no dependencies, B depends on C, and A depends on both B and C
    50  			expected: []string{"C", "B", "A"},
    51  			success:  true,
    52  		},
    53  		{
    54  			name: "complex graph",
    55  			data: []TestDependency{
    56  				{
    57  					name:         "A",
    58  					dependencies: []string{"B", "C", "D"},
    59  				},
    60  				{
    61  					name:         "B",
    62  					dependencies: []string{"C", "D", "E"},
    63  				},
    64  				{
    65  					name:         "C",
    66  					dependencies: []string{"E"},
    67  				},
    68  				{
    69  					name:         "D",
    70  					dependencies: []string{"E"},
    71  				},
    72  				{
    73  					name: "E",
    74  				},
    75  			},
    76  			expected: []string{"E", "D", "C", "B", "A"},
    77  			success:  true,
    78  		},
    79  		{
    80  			name: "graph with multiple roots",
    81  			data: []TestDependency{
    82  				{
    83  					name: "A",
    84  				},
    85  				{
    86  					name: "B",
    87  				},
    88  				{
    89  					name:         "C",
    90  					dependencies: []string{"A", "B"},
    91  				},
    92  				{
    93  					name:         "D",
    94  					dependencies: []string{"C", "E"},
    95  				},
    96  				{
    97  					name:         "E",
    98  					dependencies: []string{"F"},
    99  				},
   100  				{
   101  					name: "F",
   102  				},
   103  			},
   104  			expected: []string{"F", "B", "A", "E", "C", "D"},
   105  			success:  true,
   106  		},
   107  		{
   108  			name: "graph with multiple sinks",
   109  			data: []TestDependency{
   110  				{
   111  					name:         "A",
   112  					dependencies: []string{"B"},
   113  				},
   114  				{
   115  					name:         "B",
   116  					dependencies: []string{"C"},
   117  				},
   118  				{
   119  					name: "C",
   120  				},
   121  				{
   122  					name:         "D",
   123  					dependencies: []string{"E"},
   124  				},
   125  				{
   126  					name:         "E",
   127  					dependencies: []string{"F"},
   128  				},
   129  				{
   130  					name: "F",
   131  				},
   132  				{
   133  					name: "G",
   134  				},
   135  			},
   136  			expected: []string{"F", "C", "E", "B", "G", "D", "A"},
   137  			success:  true,
   138  		},
   139  		{
   140  			name: "graph with circular dependencies",
   141  			data: []TestDependency{
   142  				{
   143  					name:         "A",
   144  					dependencies: []string{"B"},
   145  				},
   146  				{
   147  					name:         "B",
   148  					dependencies: []string{"C"},
   149  				},
   150  				{
   151  					name:         "C",
   152  					dependencies: []string{"A"},
   153  				},
   154  			},
   155  			expected: []string{},
   156  			success:  false,
   157  		},
   158  	}
   159  
   160  	for _, tt := range tests {
   161  		t.Run(tt.name, func(t *testing.T) {
   162  			deps := make([]Dependency, len(tt.data))
   163  			for i := range tt.data {
   164  				deps[i] = tt.data[i]
   165  			}
   166  			result, err := SortDependencies(deps)
   167  			if tt.success {
   168  				require.NoError(t, err)
   169  			} else {
   170  				require.Error(t, err)
   171  			}
   172  			if !reflect.DeepEqual(result, tt.expected) {
   173  				t.Errorf("expected %v but got %v", tt.expected, result)
   174  			}
   175  		})
   176  	}
   177  }