From 84b00081d6ffcb6177852478051d090468891eb8 Mon Sep 17 00:00:00 2001 From: Kadu Artur Prussek Date: Mon, 21 Dec 2020 17:05:42 -0300 Subject: [PATCH] Improve performance to "rit create formula" command (#805) * Fix create formula msg Signed-off-by: Kadu Artur Prussek * Improve create formula tests Signed-off-by: Kadu Artur Prussek * Improve create formula tests Signed-off-by: Kadu Artur Prussek * Fix functional tests Signed-off-by: Kadu Artur Prussek --- functional/stdin/stdin_feature.json | 6 +- internal/mocks/mocks.go | 87 ++++++ pkg/cmd/create_formula.go | 101 ++++--- pkg/cmd/create_formula_test.go | 434 ++++++++++++++++++++++------ 4 files changed, 489 insertions(+), 139 deletions(-) diff --git a/functional/stdin/stdin_feature.json b/functional/stdin/stdin_feature.json index 4bfc4a3d6..2e0abbd3d 100644 --- a/functional/stdin/stdin_feature.json +++ b/functional/stdin/stdin_feature.json @@ -141,7 +141,7 @@ "action": "main" } ], - "result": "Rit formula's command needs at least 2 words" + "result": "rit formula's command needs at least 2 words following \"rit\" [ex.: rit group verb]" }, { "entry": "Create formula STDIN - no rit on formula name", @@ -157,7 +157,7 @@ "action": "main" } ], - "result": "Rit formula's command needs to start with" + "result": "rit formula's command needs to start with \"rit\" [ex.: rit group verb ]" }, { "entry": "Create formula STDIN - not allowed char", @@ -173,7 +173,7 @@ "action": "main" } ], - "result": "not allowed character on formula name" + "result": "these characters are not allowed in the formula command [\\ /,> <@ -]" }, { "entry": "Create formula STDIN - core command after rit", diff --git a/internal/mocks/mocks.go b/internal/mocks/mocks.go index 2215e1e73..aff6b9c23 100644 --- a/internal/mocks/mocks.go +++ b/internal/mocks/mocks.go @@ -24,6 +24,7 @@ import ( "github.com/ZupIT/ritchie-cli/pkg/api" "github.com/ZupIT/ritchie-cli/pkg/env" "github.com/ZupIT/ritchie-cli/pkg/formula" + "github.com/ZupIT/ritchie-cli/pkg/formula/creator/template" "github.com/ZupIT/ritchie-cli/pkg/git" "github.com/ZupIT/ritchie-cli/pkg/rtutorial" ) @@ -136,6 +137,15 @@ func (i *InputPasswordMock) Password(label string, helper ...string) (string, er return args.String(0), args.Error(1) } +type InputTextMock struct { + mock.Mock +} + +func (i *InputTextMock) Text(name string, required bool, helper ...string) (string, error) { + args := i.Called(name, required, helper) + return args.String(0), args.Error(1) +} + type InputTextValidatorMock struct { mock.Mock } @@ -146,6 +156,59 @@ func (i *InputTextValidatorMock) Text(name string, validate func(interface{}) er return args.String(0), args.Error(1) } +type FormCreator struct { + mock.Mock +} + +func (f *FormCreator) Create(cf formula.Create) error { + args := f.Called(cf) + return args.Error(0) +} + +func (f *FormCreator) Build(info formula.BuildInfo) error { + args := f.Called(info) + return args.Error(0) +} + +type WorkspaceForm struct { + mock.Mock +} + +func (w *WorkspaceForm) Add(workspace formula.Workspace) error { + args := w.Called(workspace) + return args.Error(0) +} + +func (w *WorkspaceForm) Delete(workspace formula.Workspace) error { + args := w.Called(workspace) + return args.Error(0) +} + +func (w *WorkspaceForm) List() (formula.Workspaces, error) { + args := w.Called() + return args.Get(0).(formula.Workspaces), args.Error(1) +} + +func (w *WorkspaceForm) Validate(workspace formula.Workspace) error { + args := w.Called(workspace) + return args.Error(0) +} + +func (w *WorkspaceForm) CurrentHash(formulaPath string) (string, error) { + args := w.Called(formulaPath) + return args.String(0), args.Error(1) +} + +func (w *WorkspaceForm) PreviousHash(formulaPath string) (string, error) { + args := w.Called(formulaPath) + return args.String(0), args.Error(1) +} + +func (w *WorkspaceForm) UpdateHash(formulaPath string, hash string) error { + args := w.Called(formulaPath, hash) + return args.Error(0) +} + type RepoManager struct { mock.Mock } @@ -267,3 +330,27 @@ func (t *TreeManager) Check() []api.CommandID { args := t.Called() return args.Get(0).([]api.CommandID) } + +type TemplateManagerMock struct { + mock.Mock +} + +func (tm *TemplateManagerMock) Languages() ([]string, error) { + args := tm.Called() + return args.Get(0).([]string), args.Error(1) +} + +func (tm *TemplateManagerMock) LangTemplateFiles(lang string) ([]template.File, error) { + args := tm.Called(lang) + return args.Get(0).([]template.File), args.Error(1) +} + +func (tm *TemplateManagerMock) ResolverNewPath(oldPath, newDir, lang, workspacePath string) (string, error) { + args := tm.Called(oldPath, newDir, lang, workspacePath) + return args.String(0), args.Error(1) +} + +func (tm *TemplateManagerMock) Validate() error { + args := tm.Called() + return args.Error(0) +} diff --git a/pkg/cmd/create_formula.go b/pkg/cmd/create_formula.go index c995d469d..4b8917b86 100644 --- a/pkg/cmd/create_formula.go +++ b/pkg/cmd/create_formula.go @@ -22,33 +22,41 @@ import ( "os" "path/filepath" "strings" - "time" - "github.com/kaduartur/go-cli-spinner/pkg/spinner" "github.com/spf13/cobra" "github.com/ZupIT/ritchie-cli/pkg/api" "github.com/ZupIT/ritchie-cli/pkg/formula" "github.com/ZupIT/ritchie-cli/pkg/formula/creator/template" - "github.com/ZupIT/ritchie-cli/pkg/formula/tree" "github.com/ZupIT/ritchie-cli/pkg/prompt" "github.com/ZupIT/ritchie-cli/pkg/rtutorial" "github.com/ZupIT/ritchie-cli/pkg/stdin" ) -const newWorkspace = "Type new formula workspace?" +const ( + newWorkspace = "Type new formula workspace?" + formulaCmdLabel = "Enter the new formula command: " + formulaCmdHelper = "You must create your command based in this example [rit group verb noun]" +) + +var ( + ErrFormulaCmdNotBeEmpty = errors.New("this input must not be empty") + ErrFormulaCmdMustStartWithRit = errors.New("rit formula's command needs to start with \"rit\" [ex.: rit group verb ]") + ErrInvalidFormulaCmdSize = errors.New("rit formula's command needs at least 2 words following \"rit\" [ex.: rit group verb]") + ErrInvalidCharactersFormulaCmd = errors.New(`these characters are not allowed in the formula command [\ /,> <@ -]`) +) // createFormulaCmd type for add formula command. type createFormulaCmd struct { homeDir string formula formula.CreateBuilder - workspace formula.WorkspaceAddLister + workspace formula.WorkspaceAddListHasher inText prompt.InputText inTextValidator prompt.InputTextValidator inList prompt.InputList - tplM template.Manager + template template.Manager tutorial rtutorial.Finder - tree tree.CheckerManager + tree formula.TreeChecker } // CreateFormulaCmd creates a new cmd instance. @@ -56,12 +64,12 @@ func NewCreateFormulaCmd( homeDir string, formula formula.CreateBuilder, tplM template.Manager, - workspace formula.WorkspaceAddLister, + workspace formula.WorkspaceAddListHasher, inText prompt.InputText, inTextValidator prompt.InputTextValidator, inList prompt.InputList, rtf rtutorial.Finder, - treeChecker tree.CheckerManager, + treeChecker formula.TreeChecker, ) *cobra.Command { c := createFormulaCmd{ homeDir: homeDir, @@ -70,7 +78,7 @@ func NewCreateFormulaCmd( inText: inText, inTextValidator: inTextValidator, inList: inList, - tplM: tplM, + template: tplM, tutorial: rtf, tree: treeChecker, } @@ -91,20 +99,16 @@ func NewCreateFormulaCmd( func (c createFormulaCmd) runPrompt() CommandRunnerFunc { return func(cmd *cobra.Command, args []string) error { - formulaCmd, err := c.inTextValidator.Text( - "Enter the new formula command: ", - c.surveyCmdValidator, - "You must create your command based in this example [rit group verb noun]", - ) + formulaCmd, err := c.inTextValidator.Text(formulaCmdLabel, c.surveyCmdValidator, formulaCmdHelper) if err != nil { return err } - if err := c.tplM.Validate(); err != nil { + if err := c.template.Validate(); err != nil { return err } - languages, err := c.tplM.Languages() + languages, err := c.template.Languages() if err != nil { return err } @@ -138,9 +142,12 @@ func (c createFormulaCmd) runPrompt() CommandRunnerFunc { } check := c.tree.Check() + printConflictingCommandsWarning(check) - c.create(cf) + if err := c.create(cf); err != nil { + return err + } return nil } @@ -159,42 +166,44 @@ func (c createFormulaCmd) runStdin() CommandRunnerFunc { return err } - c.create(cf) + if err := c.create(cf); err != nil { + return err + } + return nil } } -func (c createFormulaCmd) create(cf formula.Create) { - buildInfo := prompt.Bold("Creating and building formula...") - s := spinner.StartNew(buildInfo) - time.Sleep(2 * time.Second) - +func (c createFormulaCmd) create(cf formula.Create) error { if err := c.formula.Create(cf); err != nil { - err := prompt.NewError(err.Error()) - s.Error(err) - return + return err } info := formula.BuildInfo{FormulaPath: cf.FormulaPath, Workspace: cf.Workspace} if err := c.formula.Build(info); err != nil { - err := prompt.NewError(err.Error()) - s.Error(err) - return + return err + } + + hash, err := c.workspace.CurrentHash(cf.FormulaPath) + if err != nil { + return err + } + + if err := c.workspace.UpdateHash(cf.FormulaPath, hash); err != nil { + return err } + successMsg := fmt.Sprintf("%s formula successfully created!", cf.Lang) + prompt.Success(successMsg) + tutorialHolder, err := c.tutorial.Find() if err != nil { - s.Error(err) - return + return err } - createSuccess(s, cf.Lang) + buildSuccess(cf.FormulaPath, cf.FormulaCmd, tutorialHolder.Current) -} -func createSuccess(s *spinner.Spinner, lang string) { - msg := fmt.Sprintf("%s formula successfully created!", lang) - success := prompt.Green(msg) - s.Success(success) + return nil } func buildSuccess(formulaPath, formulaCmd, tutorialStatus string) { @@ -202,9 +211,10 @@ func buildSuccess(formulaPath, formulaCmd, tutorialStatus string) { if tutorialStatus == tutorialStatusEnabled { tutorialCreateFormula(formulaCmd) - } else { - prompt.Info(fmt.Sprintf("Now you can run your formula with the following command %q", formulaCmd)) + return } + + prompt.Info(fmt.Sprintf("Now you can run your formula with the following command %q", formulaCmd)) } func formulaPath(workspacePath, cmd string) string { @@ -223,19 +233,16 @@ func (c createFormulaCmd) surveyCmdValidator(cmd interface{}) error { func formulaCommandValidator(formulaCmd string) error { if len(strings.TrimSpace(formulaCmd)) < 1 { - return prompt. - NewError("this input must not be empty") + return ErrFormulaCmdNotBeEmpty } s := strings.Split(formulaCmd, " ") if s[0] != "rit" { - return prompt. - NewError("Rit formula's command needs to start with \"rit\" [ex.: rit group verb ]") + return ErrFormulaCmdMustStartWithRit } if len(s) <= 2 { - return prompt. - NewError("Rit formula's command needs at least 2 words following \"rit\" [ex.: rit group verb]") + return ErrInvalidFormulaCmdSize } if err := characterValidator(formulaCmd); err != nil { @@ -266,7 +273,7 @@ func coreCmdValidator(formulaCmd string) error { func characterValidator(formula string) error { if strings.ContainsAny(formula, `\/><,@`) { - return prompt.NewError(`not allowed character on formula name \/,><@-`) + return ErrInvalidCharactersFormulaCmd } return nil } diff --git a/pkg/cmd/create_formula_test.go b/pkg/cmd/create_formula_test.go index 80834d447..5b2fedfae 100644 --- a/pkg/cmd/create_formula_test.go +++ b/pkg/cmd/create_formula_test.go @@ -18,144 +18,400 @@ package cmd import ( "errors" + "net/http" "os" + "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/ZupIT/ritchie-cli/internal/mocks" + "github.com/ZupIT/ritchie-cli/pkg/api" + "github.com/ZupIT/ritchie-cli/pkg/formula" + "github.com/ZupIT/ritchie-cli/pkg/formula/builder" + "github.com/ZupIT/ritchie-cli/pkg/formula/creator" "github.com/ZupIT/ritchie-cli/pkg/formula/creator/template" + "github.com/ZupIT/ritchie-cli/pkg/formula/repo" "github.com/ZupIT/ritchie-cli/pkg/formula/tree" - "github.com/ZupIT/ritchie-cli/pkg/prompt" + "github.com/ZupIT/ritchie-cli/pkg/formula/workspace" + "github.com/ZupIT/ritchie-cli/pkg/git/github" + "github.com/ZupIT/ritchie-cli/pkg/git/gitlab" + "github.com/ZupIT/ritchie-cli/pkg/rtutorial" "github.com/ZupIT/ritchie-cli/pkg/stream" ) -func TestNewCreateFormulaCmd(t *testing.T) { - fileManager := stream.NewFileManager() - dirManager := stream.NewDirManager(fileManager) - tplM := template.NewManager("../../testdata", dirManager) - tChecker := tree.NewChecker(treeMock{}) - cmd := NewCreateFormulaCmd( - os.TempDir(), - formCreator{}, - tplM, - workspaceForm{}, - inputTextMock{}, - inputTextValidatorMock{}, - inputListMock{}, - TutorialFinderMock{}, - tChecker, - ) - cmd.PersistentFlags().Bool("stdin", false, "input by stdin") - if cmd == nil { - t.Errorf("NewCreateFormulaCmd got %v", cmd) - return - } - - if err := cmd.Execute(); err != nil { - t.Errorf("%s = %v, want %v", cmd.Use, err, nil) - } -} - func TestCreateFormulaCmd(t *testing.T) { type in struct { - tm template.Manager - inText prompt.InputText - inTextValidator prompt.InputTextValidator - inList prompt.InputList + inputText string + inputTextErr error + inputTextVal string + inputTextValErr error + tempValErr error + tempLanguages []string + tempLanguagesErr error + inputList string + inputListErr error + wspaceList formula.Workspaces + wspaceListErr error + wspaceAddErr error + createErr error } tests := []struct { - name string - in in - wantErr bool + name string + in in + want error }{ + { + name: "success", + in: in{ + inputTextVal: "rit test test", + tempLanguages: []string{"go", "rust", "java", "kotlin"}, + inputList: "go", + }, + }, { name: "error on input text validator", in: in{ - inTextValidator: inputTextValidatorErrorMock{}, + inputTextValErr: errors.New("error on input text"), }, - wantErr: true, + want: errors.New("error on input text"), }, { name: "error on template manager Validate func", in: in{ - inTextValidator: inputTextValidatorMock{}, - tm: TemplateManagerCustomMock{ValidateMock: func() error { - return errors.New("error on validate func") - }}, + inputTextVal: "rit test test", + tempValErr: errors.New("error on validate func"), }, - wantErr: true, + want: errors.New("error on validate func"), }, { name: "error on template manager Languages func", in: in{ - inTextValidator: inputTextValidatorMock{}, - tm: TemplateManagerCustomMock{ - ValidateMock: func() error { - return nil - }, - LanguagesMock: func() ([]string, error) { - return []string{}, errors.New("error on language func") - }, - }, + inputTextVal: "rit test test", + tempLanguagesErr: errors.New("error on language func"), }, - wantErr: true, + want: errors.New("error on language func"), }, { name: "error on input list", in: in{ - inTextValidator: inputTextValidatorMock{}, - tm: TemplateManagerCustomMock{ - ValidateMock: func() error { - return nil - }, - LanguagesMock: func() ([]string, error) { - return []string{}, nil - }, - }, - inList: inputListErrorMock{}, + inputTextVal: "rit test test", + tempLanguages: []string{"go", "java", "c", "rust"}, + inputListErr: errors.New("error to list languages"), }, - wantErr: true, + want: errors.New("error to list languages"), + }, + { + name: "list workspace error", + in: in{ + inputTextVal: "rit test test", + tempLanguages: []string{"go", "rust", "java", "kotlin"}, + inputList: "go", + wspaceListErr: errors.New("error to list workspaces"), + }, + want: errors.New("error to list workspaces"), + }, + { + name: "error function FormulaWorkspaceInput", + in: in{ + inputTextVal: "rit test test", + tempLanguages: []string{"go", "rust", "java", "kotlin"}, + inputList: newWorkspace, + inputTextErr: errors.New("error in formula workspace"), + }, + want: errors.New("error in formula workspace"), + }, + { + name: "add workspace error", + in: in{ + inputTextVal: "rit test test", + tempLanguages: []string{"go", "rust", "java", "kotlin"}, + inputList: "go", + wspaceAddErr: errors.New("error to add workspace"), + }, + want: errors.New("error to add workspace"), + }, + { + name: "formula create error", + in: in{ + inputTextVal: "rit test test", + tempLanguages: []string{"go", "rust", "java", "kotlin"}, + inputList: "go", + createErr: errors.New("error to create formula"), + }, + want: errors.New("error to create formula"), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + workspaceMock := new(mocks.WorkspaceForm) + workspaceMock.On("List").Return(tt.in.wspaceList, tt.in.wspaceListErr) + workspaceMock.On("Add", mock.Anything).Return(tt.in.wspaceAddErr) + workspaceMock.On("CurrentHash", mock.Anything).Return("48d47029-2abf-4a2e-b5f2-f5b60471423e", nil) + workspaceMock.On("UpdateHash", mock.Anything, mock.Anything).Return(nil) + + templateManagerMock := new(mocks.TemplateManagerMock) + templateManagerMock.On("Validate").Return(tt.in.tempValErr) + templateManagerMock.On("Languages").Return(tt.in.tempLanguages, tt.in.tempLanguagesErr) + + formulaCreatorMock := new(mocks.FormCreator) + formulaCreatorMock.On("Create", mock.Anything).Return(tt.in.createErr) + formulaCreatorMock.On("Build", mock.Anything).Return(nil) + + inputTextMock := new(mocks.InputTextMock) + inputTextMock.On("Text", mock.Anything, mock.Anything, mock.Anything).Return(tt.in.inputText, tt.in.inputTextErr) + + inputTextValidatorMock := new(mocks.InputTextValidatorMock) + inputTextValidatorMock.On("Text", mock.Anything, mock.Anything, mock.Anything).Return(tt.in.inputTextVal, tt.in.inputTextValErr) + + inputListMock := new(mocks.InputListMock) + inputListMock.On("List", mock.Anything, mock.Anything, mock.Anything).Return(tt.in.inputList, tt.in.inputListErr) + + tutorialMock := new(mocks.TutorialFindSetterMock) + tutorialMock.On("Find").Return(rtutorial.TutorialHolder{Current: "enabled"}, nil) + + treeMock := new(mocks.TreeManager) + treeMock.On("Check").Return([]api.CommandID{}) + createFormulaCmd := NewCreateFormulaCmd( os.TempDir(), - formCreator{}, - tt.in.tm, - workspaceForm{}, - tt.in.inText, - tt.in.inTextValidator, - tt.in.inList, - TutorialFinderMock{}, - tree.CheckerManager{}, + formulaCreatorMock, + templateManagerMock, + workspaceMock, + inputTextMock, + inputTextValidatorMock, + inputListMock, + tutorialMock, + treeMock, ) + // TODO: remove it after being deprecated createFormulaCmd.PersistentFlags().Bool("stdin", false, "input by stdin") - if err := createFormulaCmd.Execute(); (err != nil) != tt.wantErr { - t.Errorf("%s = %v, want %v", createFormulaCmd.Use, err, nil) - } + got := createFormulaCmd.Execute() + assert.Equal(t, tt.want, got) }) } } -type TemplateManagerCustomMock struct { - LanguagesMock func() ([]string, error) - LangTemplateFilesMock func(lang string) ([]template.File, error) - ResolverNewPathMock func(oldPath, newDir, lang, workspacePath string) (string, error) - ValidateMock func() error -} +func TestCreateFormula(t *testing.T) { + ritchieHomeDir := filepath.Join(os.TempDir(), ".rit_create_formula") + workDir := filepath.Join(os.TempDir(), ".ritchie-formulas-local") + fileManager := stream.NewFileManager() + dirManager := stream.NewDirManager(fileManager) -func (tm TemplateManagerCustomMock) Languages() ([]string, error) { - return tm.LanguagesMock() -} + _ = dirManager.Remove(ritchieHomeDir) + _ = dirManager.Remove(workDir) + + cf := formula.Create{ + FormulaCmd: "rit test test", + Lang: "go", + Workspace: formula.Workspace{ + Name: "default", + Dir: workDir, + }, + FormulaPath: filepath.Join(workDir, "test", "test"), + } + + type in struct { + createFormErr error + buildFormErr error + currentHash string + currentHashErr error + updateHashErr error + tutorialHolder rtutorial.TutorialHolder + tutorialErr error + } -func (tm TemplateManagerCustomMock) LangTemplateFiles(lang string) ([]template.File, error) { - return tm.LangTemplateFilesMock(lang) + tests := []struct { + name string + in in + withoutMock bool + want error + }{ + { + name: "success without mock", + withoutMock: true, + }, + { + name: "success mocked", + in: in{ + currentHash: "a6edc906-2f9f-5fb2-a373-efac406f0ef2", + }, + }, + { + name: "success with tutorial enabled", + in: in{ + currentHash: "a6edc906-2f9f-5fb2-a373-efac406f0ef2", + tutorialHolder: rtutorial.TutorialHolder{ + Current: "enabled", + }, + }, + }, + { + name: "create formula error", + in: in{ + createFormErr: errors.New("error to create formula"), + }, + want: errors.New("error to create formula"), + }, + { + name: "build formula error", + in: in{ + buildFormErr: errors.New("error to build formula"), + }, + want: errors.New("error to build formula"), + }, + { + name: "current hash error", + in: in{ + currentHashErr: errors.New("error to create current formula hash"), + }, + want: errors.New("error to create current formula hash"), + }, + { + name: "update hash error", + in: in{ + updateHashErr: errors.New("error to update formula hash"), + }, + want: errors.New("error to update formula hash"), + }, + { + name: "tutorial disable", + in: in{ + tutorialHolder: rtutorial.TutorialHolder{ + Current: "disable", + }, + }, + }, + { + name: "tutorial error", + in: in{ + tutorialErr: errors.New("error to find tutorial"), + }, + want: errors.New("error to find tutorial"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var createForm createFormulaCmd + if !tt.withoutMock { + creatorMock := new(mocks.FormCreator) + creatorMock.On("Create", mock.Anything).Return(tt.in.createFormErr) + creatorMock.On("Build", mock.Anything).Return(tt.in.buildFormErr) + workspaceMock := new(mocks.WorkspaceForm) + workspaceMock.On("CurrentHash", mock.Anything).Return(tt.in.currentHash, tt.in.currentHashErr) + workspaceMock.On("UpdateHash", mock.Anything, mock.Anything).Return(tt.in.updateHashErr) + tutorialMock := new(mocks.TutorialFindSetterMock) + tutorialMock.On("Find").Return(tt.in.tutorialHolder, tt.in.tutorialErr) + + createForm = createFormulaCmd{ + formula: creatorMock, + workspace: workspaceMock, + tutorial: tutorialMock, + } + } else { + createForm = createFormulaCmdDeps(ritchieHomeDir, dirManager, fileManager) + } + + got := createForm.create(cf) + assert.Equal(t, tt.want, got) + + if tt.withoutMock { + assert.DirExists(t, ritchieHomeDir) + + hashesDir := filepath.Join(ritchieHomeDir, "hashes") + assert.DirExists(t, hashesDir) + + reposDir := filepath.Join(ritchieHomeDir, "repos") + assert.DirExists(t, reposDir) + assert.DirExists(t, filepath.Join(reposDir, "local-default")) + assert.FileExists(t, filepath.Join(reposDir, "local-default", "tree.json")) + + assert.FileExists(t, filepath.Join(hashesDir, "-tmp-.ritchie-formulas-local-test-test.txt")) + + assert.FileExists(t, filepath.Join(reposDir, "repositories.json")) + } + }) + } } -func (tm TemplateManagerCustomMock) ResolverNewPath(oldPath, newDir, lang, workspacePath string) (string, error) { - return tm.ResolverNewPathMock(oldPath, newDir, lang, workspacePath) + +func TestFormulaCommandValidator(t *testing.T) { + tests := []struct { + name string + formulaCmd string + want error + }{ + { + name: "success", + formulaCmd: "rit test test", + }, + { + name: "error empty command", + want: ErrFormulaCmdNotBeEmpty, + }, + { + name: "invalid start formula command", + formulaCmd: "richie test test", + want: ErrFormulaCmdMustStartWithRit, + }, + { + name: "invalid formula command size", + formulaCmd: "rit test", + want: ErrInvalidFormulaCmdSize, + }, + { + name: "invalid characters in formula command", + formulaCmd: "rit test test@test", + want: ErrInvalidCharactersFormulaCmd, + }, + { + name: "invalid formula command with core command", + formulaCmd: "rit add test", + want: errors.New("core command verb \"add\" after rit\nUse your formula group before the verb\nExample: rit aws list bucket\n"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := formulaCommandValidator(tt.formulaCmd) + assert.Equal(t, tt.want, got) + }) + } } -func (tm TemplateManagerCustomMock) Validate() error { - return tm.ValidateMock() + +func createFormulaCmdDeps(ritchieHomeDir string, dirManager stream.DirManager, fileManager stream.FileManager) createFormulaCmd { + treeGen := tree.NewGenerator(dirManager, fileManager) + githubRepo := github.NewRepoManager(http.DefaultClient) + gitlabRepo := gitlab.NewRepoManager(http.DefaultClient) + + repoProviders := formula.NewRepoProviders() + repoProviders.Add("Github", formula.Git{Repos: githubRepo, NewRepoInfo: github.NewRepoInfo}) + repoProviders.Add("Gitlab", formula.Git{Repos: gitlabRepo, NewRepoInfo: gitlab.NewRepoInfo}) + repoCreator := repo.NewCreator(ritchieHomeDir, repoProviders, dirManager, fileManager) + repoLister := repo.NewLister(ritchieHomeDir, fileManager) + repoWriter := repo.NewWriter(ritchieHomeDir, fileManager) + repoListWriteCreator := repo.NewListWriteCreator(repoLister, repoCreator, repoWriter) + + repoListWriter := repo.NewListWriter(repoLister, repoWriter) + repoDeleter := repo.NewDeleter(ritchieHomeDir, repoListWriter, dirManager) + repoAdder := repo.NewAdder(ritchieHomeDir, repoListWriteCreator, repoDeleter, treeGen, fileManager) + + treeManager := tree.NewTreeManager(ritchieHomeDir, repoLister, api.CoreCmds, fileManager, nil) + tmpManager := template.NewManager("../../testdata", dirManager) + createManager := creator.NewCreator(treeManager, dirManager, fileManager, tmpManager) + formBuildLocal := builder.NewBuildLocal(ritchieHomeDir, dirManager, repoAdder) + createBuilder := formula.NewCreateBuilder(createManager, formBuildLocal) + buildLocal := builder.NewBuildLocal(ritchieHomeDir, dirManager, repoAdder) + wspaceManager := workspace.New(ritchieHomeDir, os.TempDir(), dirManager, fileManager, buildLocal) + tutorialFinder := rtutorial.NewFinder(ritchieHomeDir, fileManager) + + return createFormulaCmd{ + formula: createBuilder, + workspace: wspaceManager, + tutorial: tutorialFinder, + } }