|
1 | 1 | package workflow |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "encoding/json" |
4 | 5 | "os" |
5 | 6 | "path/filepath" |
6 | 7 | "testing" |
@@ -124,3 +125,75 @@ func TestActionCacheTrailingNewline(t *testing.T) { |
124 | 125 | t.Error("Cache file should end with a trailing newline for prettier compliance") |
125 | 126 | } |
126 | 127 | } |
| 128 | + |
| 129 | +func TestActionCacheSortedEntries(t *testing.T) { |
| 130 | + // Create temporary directory for testing |
| 131 | + tmpDir := t.TempDir() |
| 132 | + |
| 133 | + // Create cache and add entries in non-alphabetical order |
| 134 | + cache := NewActionCache(tmpDir) |
| 135 | + cache.Set("zzz/last-action", "v1", "sha111") |
| 136 | + cache.Set("actions/checkout", "v5", "sha222") |
| 137 | + cache.Set("mmm/middle-action", "v2", "sha333") |
| 138 | + cache.Set("actions/setup-node", "v4", "sha444") |
| 139 | + cache.Set("aaa/first-action", "v3", "sha555") |
| 140 | + |
| 141 | + // Save to disk |
| 142 | + err := cache.Save() |
| 143 | + if err != nil { |
| 144 | + t.Fatalf("Failed to save cache: %v", err) |
| 145 | + } |
| 146 | + |
| 147 | + // Read the file content |
| 148 | + cachePath := filepath.Join(tmpDir, ".github", "aw", CacheFileName) |
| 149 | + data, err := os.ReadFile(cachePath) |
| 150 | + if err != nil { |
| 151 | + t.Fatalf("Failed to read cache file: %v", err) |
| 152 | + } |
| 153 | + |
| 154 | + content := string(data) |
| 155 | + |
| 156 | + // Verify that entries appear in alphabetical order by checking their positions |
| 157 | + entries := []string{ |
| 158 | + "aaa/first-action@v3", |
| 159 | + "actions/checkout@v5", |
| 160 | + "actions/setup-node@v4", |
| 161 | + "mmm/middle-action@v2", |
| 162 | + "zzz/last-action@v1", |
| 163 | + } |
| 164 | + |
| 165 | + lastPos := -1 |
| 166 | + for _, entry := range entries { |
| 167 | + pos := indexOf(content, entry) |
| 168 | + if pos == -1 { |
| 169 | + t.Errorf("Entry %s not found in cache file", entry) |
| 170 | + continue |
| 171 | + } |
| 172 | + if pos < lastPos { |
| 173 | + t.Errorf("Entry %s appears before previous entry (not sorted)", entry) |
| 174 | + } |
| 175 | + lastPos = pos |
| 176 | + } |
| 177 | + |
| 178 | + // Also verify the file is valid JSON |
| 179 | + var loadedCache ActionCache |
| 180 | + err = json.Unmarshal(data, &loadedCache) |
| 181 | + if err != nil { |
| 182 | + t.Fatalf("Saved cache is not valid JSON: %v", err) |
| 183 | + } |
| 184 | + |
| 185 | + // Verify all entries are present |
| 186 | + if len(loadedCache.Entries) != 5 { |
| 187 | + t.Errorf("Expected 5 entries, got %d", len(loadedCache.Entries)) |
| 188 | + } |
| 189 | +} |
| 190 | + |
| 191 | +// indexOf returns the index of substr in s, or -1 if not found |
| 192 | +func indexOf(s, substr string) int { |
| 193 | + for i := 0; i <= len(s)-len(substr); i++ { |
| 194 | + if s[i:i+len(substr)] == substr { |
| 195 | + return i |
| 196 | + } |
| 197 | + } |
| 198 | + return -1 |
| 199 | +} |
0 commit comments