fuzzyworld

template / ci-testing / files / profile_test.go

Branch ci-testing · default branch · all branches

profile_test.go

Blame: the commit that last changed each line · file · history

c62570e2 2022-09-23 Pavel Safronov1package main
2
3import (
9573ca02 2022-11-16 Pavel Safronov4 "io/fs"
c3fc7a22 2022-10-30 Pavel Safronov5 "os"
6 "os/exec"
7 "os/user"
8 "path/filepath"
9573ca02 2022-11-16 Pavel Safronov9 "runtime"
c62570e2 2022-09-23 Pavel Safronov10 "testing"
c3fc7a22 2022-10-30 Pavel Safronov11
12 "github.com/stretchr/testify/assert"
c62570e2 2022-09-23 Pavel Safronov13)
14
763c260d 2022-10-06 Pavel Safronov15func TestValidateProfile(t *testing.T) {
16 testSuccess := func(profile Profile) {
b0586433 2022-10-21 Pavel Safronov17 err := validateProfile(&profile)
763c260d 2022-10-06 Pavel Safronov18 if err != nil {
19 t.Errorf("Expected to validate profile '%v', but failed: %v", profile.Name, err)
20 }
21 }
9573ca02 2022-11-16 Pavel Safronov22 testFailure := func(profile Profile, expectedErrStr string) {
b0586433 2022-10-21 Pavel Safronov23 err := validateProfile(&profile)
9573ca02 2022-11-16 Pavel Safronov24 assert.NotNil(t, err, "Expected to fail to validate profile '%v', but succeeded")
25 assert.Contains(t, err.Error(), expectedErrStr, "Expected error to contain '%v', but it didn't", expectedErrStr)
763c260d 2022-10-06 Pavel Safronov26 }
27
28 testSuccess(Profile{
29 Type: FileType,
30 Name: "daily",
1a02ef4e 2022-10-21 Pavel Safronov31 NamePatterns: []ParameterizedText{"{{.Date}}"},
8c15a714 2022-11-04 Pavel Safronov32 Path: "~/test/dir",
763c260d 2022-10-06 Pavel Safronov33 })
05f9e8ef 2022-10-06 Pavel Safronov34 testSuccess(Profile{
35 Type: FileType,
36 Name: "daily",
1a02ef4e 2022-10-21 Pavel Safronov37 NamePatterns: []ParameterizedText{"{{.Date}}"},
b0586433 2022-10-21 Pavel Safronov38 File: File{
39 Template: "foo",
40 },
8c15a714 2022-11-04 Pavel Safronov41 Path: "~/test/dir",
05f9e8ef 2022-10-06 Pavel Safronov42 })
763c260d 2022-10-06 Pavel Safronov43
44 testFailure(Profile{
45 Name: "",
9573ca02 2022-11-16 Pavel Safronov46 }, "Profile name is required")
763c260d 2022-10-06 Pavel Safronov47 testFailure(Profile{
48 Name: "list",
9573ca02 2022-11-16 Pavel Safronov49 }, "forbidden profile name 'list'")
763c260d 2022-10-06 Pavel Safronov50 testFailure(Profile{
51 Name: "get",
9573ca02 2022-11-16 Pavel Safronov52 }, "forbidden profile name 'get'")
763c260d 2022-10-06 Pavel Safronov53 testFailure(Profile{
54 Type: FileType,
55 Name: "daily",
9573ca02 2022-11-16 Pavel Safronov56 }, "namePatterns is required")
763c260d 2022-10-06 Pavel Safronov57 testFailure(Profile{
9573ca02 2022-11-16 Pavel Safronov58 Type: FileType,
59 Name: "daily",
60 NamePatterns: []ParameterizedText{"blah"},
61 }, "path is not specified for profile daily, which has Type=file")
8c15a714 2022-11-04 Pavel Safronov62
9573ca02 2022-11-16 Pavel Safronov63 testFailure(Profile{
64 Type: FolderType,
65 Name: "daily",
66 NamePatterns: []ParameterizedText{"test"},
67 }, "path is required for profile daily, which has Type=folder")
05f9e8ef 2022-10-06 Pavel Safronov68 testFailure(Profile{
69 Type: FolderType,
70 Name: "daily",
1a02ef4e 2022-10-21 Pavel Safronov71 NamePatterns: []ParameterizedText{"test"},
b0586433 2022-10-21 Pavel Safronov72 File: File{
73 Template: "bar",
74 },
9573ca02 2022-11-16 Pavel Safronov75 }, "file template is not supported for profile daily, which has Type=folder")
05f9e8ef 2022-10-06 Pavel Safronov76 testFailure(Profile{
77 Type: ScriptType,
78 Name: "daily",
1a02ef4e 2022-10-21 Pavel Safronov79 NamePatterns: []ParameterizedText{"test", "test2"},
9573ca02 2022-11-16 Pavel Safronov80 }, "multiple name patterns are not supported for profile daily, which has Type=script")
81 testFailure(Profile{
82 Type: FileType,
83 Name: "daily",
84 NamePatterns: []ParameterizedText{"test", "test2"},
85 }, "path is not specified for profile daily, which has Type=file")
86 testFailure(Profile{
87 Type: FileType,
88 Name: "daily",
89 NamePatterns: []ParameterizedText{"test", ""},
90 }, "name pattern is required for pattern index 1 of profile daily")
763c260d 2022-10-06 Pavel Safronov91
92 for _, profile := range defaultConfig().Profiles {
93 testSuccess(profile)
94 }
95}
96
ae89a42a 2022-11-02 Pavel Safronov97func TestFindProfileIndex(t *testing.T) {
c62570e2 2022-09-23 Pavel Safronov98 config := Config{
99 Profiles: []Profile{
100 {
101 Name: "daily",
102 },
103 {
104 IsDefault: true,
105 Name: "notes",
106 },
107 },
108 }
109 testSuccess := func(profileName string, expectedProfileName string) {
ae89a42a 2022-11-02 Pavel Safronov110 index, err := findProfileIndex(config.Profiles, profileName)
c62570e2 2022-09-23 Pavel Safronov111 if err != nil {
112 t.Errorf("Failed to find profile '%v': %v", profileName, err)
113 }
ae89a42a 2022-11-02 Pavel Safronov114 profile := config.Profiles[index]
c62570e2 2022-09-23 Pavel Safronov115 if profile.Name != expectedProfileName {
116 t.Errorf("Asked for profile '%v', expected '%v', got '%v'", profileName, expectedProfileName, profile.Name)
117 }
118 }
119 testFailure := func(profileName string) {
ae89a42a 2022-11-02 Pavel Safronov120 _, err := findProfileIndex(config.Profiles, profileName)
c62570e2 2022-09-23 Pavel Safronov121 if err == nil {
122 t.Errorf("Expected to fail to find profile '%v', but succeeded", profileName)
123 }
124 }
125
126 testSuccess("daily", "daily")
127 testSuccess("notes", "notes")
128
ae89a42a 2022-11-02 Pavel Safronov129 testFailure("")
c62570e2 2022-09-23 Pavel Safronov130 testFailure("non-existent")
05f9e8ef 2022-10-06 Pavel Safronov131
132 config.Profiles[1].IsDefault = false
133 testFailure("")
134 testFailure("non-default")
c62570e2 2022-09-23 Pavel Safronov135}
c3fc7a22 2022-10-30 Pavel Safronov136
ae89a42a 2022-11-02 Pavel Safronov137func TestFindDefaultProfile(t *testing.T) {
138 _, err := findDefaultProfile(defaultConfig().Profiles)
139 assert.Nil(t, err, "Expected to find default profile, but failed")
140
141 _, err = findDefaultProfile([]Profile{})
142 assert.NotNil(t, err, "Expected to fail to find default profile, but succeeded")
143}
144
c3fc7a22 2022-10-30 Pavel Safronov145func TestCreateEntity(t *testing.T) {
146 // setup
147 now := testNow()
148 cwd := "~/test/dir"
149 projectName := "project-name"
150 extras := map[string]string{
151 "foo": "bar",
152 }
153 patternData := testPrePatternData()
154
155 testFolder := func() {
156 monkeyPatchCalls := applyTestMonkeyPatch(t, monkeyPatch{
157 OSMkdir: func(path string, perm os.FileMode) error { return nil },
158 OSChdir: func(dir string) error { return nil },
159 OSWriteFile: func(filename string, data []byte, perm os.FileMode) error { return nil },
160 })
161
162 profile := Profile{
163 Type: FolderType,
164 Files: []FileInFolder{
165 {
166 Name: "readme.md",
167 File: File{
168 Template: "blah",
169 },
170 },
171 {
172 Name: "test.txt",
173 File: File{
174 Template: "foo",
175 },
176 },
177 },
178 }
179
180 newName := "new-name"
181 expectedFullPath := filepath.Clean("~/test/dir/" + newName)
182 fullPath, err := createEntity(now, profile, cwd, newName, projectName, extras, patternData)
183 assert.Nil(t, err)
184 assert.Equal(t, expectedFullPath, fullPath)
185 assert.Equal(t, 1, len(monkeyPatchCalls.OSChdirCalls))
186 assert.Equal(t, expectedFullPath, monkeyPatchCalls.OSChdirCalls[0].dir)
5e424f1b 2022-11-12 Pavel Safronov187 assert.Equal(t, 3, len(monkeyPatchCalls.OSMkdirCalls))
c3fc7a22 2022-10-30 Pavel Safronov188 assert.Equal(t, expectedFullPath, monkeyPatchCalls.OSMkdirCalls[0].path)
189 assert.Equal(t, 2, len(monkeyPatchCalls.OSWriteFileCalls))
190 assert.Equal(t, filepath.Clean(expectedFullPath+"/readme.md"), monkeyPatchCalls.OSWriteFileCalls[0].filename)
191 assert.Equal(t, []byte("blah"), monkeyPatchCalls.OSWriteFileCalls[0].data)
192 assert.Equal(t, filepath.Clean(expectedFullPath+"/test.txt"), monkeyPatchCalls.OSWriteFileCalls[1].filename)
193 assert.Equal(t, []byte("foo"), monkeyPatchCalls.OSWriteFileCalls[1].data)
194 }
195
196 testFile := func() {
197 monkeyPatchCalls := applyTestMonkeyPatch(t, monkeyPatch{
198 OSWriteFile: func(filename string, data []byte, perm os.FileMode) error { return nil },
199 })
200
201 profile := Profile{
202 Type: FileType,
203 File: File{
204 Template: "blah",
205 },
206 }
207 newName := "new-name.md"
208 expectedFullPath := filepath.Clean("~/test/dir/" + newName)
209 fullPath, err := createEntity(now, profile, cwd, newName, projectName, extras, patternData)
210 assert.Nil(t, err)
211 assert.Equal(t, expectedFullPath, fullPath)
212 assert.Equal(t, 1, len(monkeyPatchCalls.OSWriteFileCalls))
213 assert.Equal(t, expectedFullPath, monkeyPatchCalls.OSWriteFileCalls[0].filename)
214 assert.Equal(t, []byte("blah"), monkeyPatchCalls.OSWriteFileCalls[0].data)
215 }
216
217 testScript := func() {
218 profile := Profile{
219 Type: ScriptType,
220 PostScripts: []ParameterizedText{
221 "{{.ProjectName}}-{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Minute}}-{{.Second}}-{{.Extras.key1}}",
222 },
223 }
224 newName := "new-name.md"
225 expectedFullPath := filepath.Clean("~/test/dir/" + newName)
226 fullPath, err := createEntity(now, profile, cwd, newName, projectName, extras, patternData)
227 assert.Nil(t, err)
228 assert.Equal(t, expectedFullPath, fullPath)
229 }
230
231 testFolder()
232
233 testFile()
234
235 testScript()
236}
237
9573ca02 2022-11-16 Pavel Safronov238type testFile struct {
239 name string
240 isDir bool
241}
242
243func (f testFile) Name() string { return f.name }
244func (f testFile) IsDir() bool { return f.isDir }
245func (f testFile) Type() fs.FileMode { return 0 }
246func (f testFile) Info() (fs.FileInfo, error) { return nil, nil }
247
c3fc7a22 2022-10-30 Pavel Safronov248func TestProcessProfile(t *testing.T) {
249 cwd := filepath.Clean("~/test/dir")
9573ca02 2022-11-16 Pavel Safronov250 createDirEntry := func(name string, isDir bool) os.DirEntry {
251 entry := testFile{name: name, isDir: isDir}
252 return entry
253 }
254 var monkeyPatchCalls *monkeyPatchCalls
255 configureMonkeyPatching := func() {
256 monkeyPatchCalls = applyTestMonkeyPatch(t, monkeyPatch{
257 ExecCommand: func(command string, args ...string) *exec.Cmd {
748e3056 2022-11-19 Pavel Safronov258 shell, shellArgs := shellCommandAndArgs("echo")
259 return exec.Command(shell, shellArgs...)
9573ca02 2022-11-16 Pavel Safronov260 },
261 OSChdir: func(dir string) error { return nil },
262 OSGetwd: func() (dir string, err error) { return cwd, nil },
263 OSReadDir: func(dirname string) ([]os.DirEntry, error) {
264 return []os.DirEntry{
265 createDirEntry("dir1", true),
266 createDirEntry("dir2", true),
267 createDirEntry("file1", false),
268 createDirEntry("file2", false),
269 }, nil
270 },
271 OSWriteFile: func(filename string, data []byte, perm os.FileMode) error {
272 return nil
273 },
274 })
275 }
c3fc7a22 2022-10-30 Pavel Safronov276
277 projectName := "project-name"
278 extras := map[string]string{
279 "foo": "bar",
280 }
a5ad914b 2022-10-30 Pavel Safronov281
9573ca02 2022-11-16 Pavel Safronov282 usr, err := user.Current()
283 assert.Nil(t, err)
284 assert.NotNil(t, usr)
a5ad914b 2022-10-30 Pavel Safronov285
9573ca02 2022-11-16 Pavel Safronov286 testSuccess := func(profile Profile) {
287 configureMonkeyPatching()
a5ad914b 2022-10-30 Pavel Safronov288 errors := processProfile(profile, projectName, extras, *usr)
289 assert.Equal(t, 0, len(errors))
9573ca02 2022-11-16 Pavel Safronov290 for _, error := range errors {
291 assert.Nil(t, error)
292 }
a5ad914b 2022-10-30 Pavel Safronov293 }
9573ca02 2022-11-16 Pavel Safronov294 testFailure := func(profile Profile, errorCount int, errorStr string) {
295 configureMonkeyPatching()
296 errors := processProfile(profile, projectName, extras, *usr)
297 assert.Equal(t, errorCount, len(errors))
298 allErrorsText := ""
299 for _, err := range errors {
300 allErrorsText += err.Error()
a5ad914b 2022-10-30 Pavel Safronov301 }
9573ca02 2022-11-16 Pavel Safronov302 assert.Contains(t, allErrorsText, errorStr)
303 }
304 testSingleFailure := func(profile Profile, errorStr string) {
305 testFailure(profile, 1, errorStr)
306 }
a5ad914b 2022-10-30 Pavel Safronov307
9573ca02 2022-11-16 Pavel Safronov308 // this profile will be built up from failing to eventually passing
309 currentOS := getCurrentOs()
310 profile := Profile{
311 IsDisabled: true,
a5ad914b 2022-10-30 Pavel Safronov312 }
9573ca02 2022-11-16 Pavel Safronov313 testSingleFailure(profile, "Profile is disabled, doing nothing")
314 profile.IsDisabled = false
315 profile.OS = getOtherOs(currentOS)
316 testSingleFailure(profile, "This profile is not supported on this OS, doing nothing.")
317 profile.OS = currentOS
318 // testSingleFailure(profile, "unable to create post scripts: no post scripts specified")
a5ad914b 2022-10-30 Pavel Safronov319
9573ca02 2022-11-16 Pavel Safronov320 profile.NamePatterns = []ParameterizedText{}
321 profile.Type = FileType
322 testSingleFailure(profile, "couldn't find a good new name")
a5ad914b 2022-10-30 Pavel Safronov323
9573ca02 2022-11-16 Pavel Safronov324 profile.NamePatterns = []ParameterizedText{"file1"}
325 profile.RunPostscriptOnFailure = true
326 testSingleFailure(profile, "couldn't find a good new name")
327
328 profile.NamePatterns = []ParameterizedText{"file3"}
329 profile.PostScripts = []ParameterizedText{"echo {{.ProjectName}}-{{.Year}}"}
330 profile.Path = "~/test/dir"
331 testSuccess(profile)
332 assert.Equal(t, 1, len(monkeyPatchCalls.ExecCommandCalls), "calls to ExecCommand")
333 assert.Equal(t, 1, len(monkeyPatchCalls.OSChdirCalls), "calls to OSChdir")
334 assert.Equal(t, 1, len(monkeyPatchCalls.OSGetwdCalls), "calls to OSGetwd")
335 assert.Equal(t, 1, len(monkeyPatchCalls.OSReadDirCalls), "calls to OSReadDir")
336 assert.Equal(t, 1, len(monkeyPatchCalls.OSWriteFileCalls), "calls to OSWriteFile")
337
338 profile.PostScripts = []ParameterizedText{"echo ''"}
339 testSuccess(profile)
340 assert.Equal(t, 1, len(monkeyPatchCalls.ExecCommandCalls), "calls to ExecCommand")
341 assert.Equal(t, 1, len(monkeyPatchCalls.OSChdirCalls), "calls to OSChdir")
342 assert.Equal(t, 1, len(monkeyPatchCalls.OSGetwdCalls), "calls to OSGetwd")
343 assert.Equal(t, 1, len(monkeyPatchCalls.OSReadDirCalls), "calls to OSReadDir")
344 assert.Equal(t, 1, len(monkeyPatchCalls.OSWriteFileCalls), "calls to OSWriteFile")
345}
346
347func getCurrentOs() OSType {
348 os := runtime.GOOS
349 if os == "windows" {
350 return "Windows"
351 } else {
352 return "Mac"
353 }
354}
355func getOtherOs(currentOs OSType) OSType {
9b0177be 2022-11-19 Pavel Safronov356 if currentOs == "Windows" {
9573ca02 2022-11-16 Pavel Safronov357 return "Mac"
358 }
359 return "Windows"
c3fc7a22 2022-10-30 Pavel Safronov360}