You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: formatter_test.go
    path of file: ./repos/horusec/internal/services/formatters/go/nancy
    
    the code of the file until where you have to start completion: // Copyright 2021 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package nancy

import (
	"errors"
	"os"
	"path/filepath"
	"testing"

	"github.com/ZupIT/horusec-devkit/pkg/entities/analysis"
	"github.com/ZupIT/horusec-devkit/pkg/enums/confidence"
	"github.com/ZupIT/horusec-devkit/pkg/enums/languages"
	"github.com/ZupIT/horusec-devkit/pkg/enums/tools"
	"github.com/stretchr/testify/assert"

	"github.com/ZupIT/horusec/config"
	"github.com/ZupIT/horusec/internal/entities/toolsconfig"
	"github.com/ZupIT/horusec/internal/helpers/messages"
	"github.com/ZupIT/horusec/internal/services/formatters"
	"github.com/ZupIT/horusec/internal/utils/testutil"
)

func TestParseOutput(t *testing.T) {
	t.Run("should success parse output to analysis", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "1243567890")
		analysis := new(analysis.Analysis)

		cfg := config.New()
		cfg.ProjectPath = testutil.CreateHorusecAnalysisDirectory(t, analysis, testutil.GoExample1)

		dockerAPIControllerMock := testutil.NewDockerMock()
		dockerAPIControllerMock.On("SetAnalysisID")
		dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil)

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

		formatter := NewFormatter(service)
		formatter.StartAnalysis("")

		assert.False(t, analysis.HasErrors(), "Expected no errors on analysis: %s", analysis.Errors)
		assert.Len(t, analysis.AnalysisVulnerabilities, 4)

		for _, v := range analysis.AnalysisVulnerabilities {
			vuln := v.Vulnerability

			expectedGoModPath := filepath.Join(cfg.ProjectPath, "go.mod")
			expectedGoSumPath := filepath.Join(cfg.ProjectPath, "go.sum")

			assert.Equal(t, languages.Go, vuln.Language, "Expected Go as vulnerability language")
			assert.Equal(t, tools.Nancy, vuln.SecurityTool, "Expected nancy as security tool")
			assert.NotEmpty(t, vuln.Severity, "Expected not empty vulnerability severity")
			assert.NotEmpty(t, vuln.Details, "Expected not empty vulnerability details")
			assert.Equal(t, confidence.High, vuln.Confidence, "Expected high as vulnerability confidence")
			assert.NotEmpty(t, vuln.Code, "Expected not empty vulnerability code")
			assert.NotEmpty(t, vuln.Line, "Expected not empty vulnerability line")

			assert.Condition(
				t,
				func() bool {
					return vuln.File == expectedGoModPath || vuln.File == expectedGoSumPath
				},
				"Expected vulnerability file %q to be %q or %q", vuln.File, expectedGoModPath, expectedGoSumPath,
	
    
func TestParseOutput(t *testing.T) {
	t.Run("should success parse output to analysis", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "1243567890")
		analysis := new(analysis.Analysis)

		cfg := config.New()
		cfg.ProjectPath = testutil.CreateHorusecAnalysisDirectory(t, analysis, testutil.GoExample1)

		dockerAPIControllerMock := testutil.NewDockerMock()
		dockerAPIControllerMock.On("SetAnalysisID")
		dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil)

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

		formatter := NewFormatter(service)
		formatter.StartAnalysis("")

		assert.False(t, analysis.HasErrors(), "Expected no errors on analysis: %s", analysis.Errors)
		assert.Len(t, analysis.AnalysisVulnerabilities, 4)

		for _, v := range analysis.AnalysisVulnerabilities {
			vuln := v.Vulnerability

			expectedGoModPath := filepath.Join(cfg.ProjectPath, "go.mod")
			expectedGoSumPath := filepath.Join(cfg.ProjectPath, "go.sum")

			assert.Equal(t, languages.Go, vuln.Language, "Expected Go as vulnerability language")
			assert.Equal(t, tools.Nancy, vuln.SecurityTool, "Expected nancy as security tool")
			assert.NotEmpty(t, vuln.Severity, "Expected not empty vulnerability severity")
			assert.NotEmpty(t, vuln.Details, "Expected not empty vulnerability details")
			assert.Equal(t, confidence.High, vuln.Confidence, "Expected high as vulnerability confidence")
			assert.NotEmpty(t, vuln.Code, "Expected not empty vulnerability code")
			assert.NotEmpty(t, vuln.Line, "Expected not empty vulnerability line")

			assert.Condition(
				t,
				func() bool {
					return vuln.File == expectedGoModPath || vuln.File == expectedGoSumPath
				},
				"Expected vulnerability file %q to be %q or %q", vuln.File, expectedGoModPath, expectedGoSumPath,
			)
		}
	})

	t.Run("should success parse output empty to analysis", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "1243567890")
		analysis := new(analysis.Analysis)

		cfg := config.New()

		dockerAPIControllerMock := testutil.NewDockerMock()
		dockerAPIControllerMock.On("SetAnalysisID")
		dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("", nil)

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

		formatter := NewFormatter(service)
		formatter.StartAnalysis("")

		assert.Len(t, analysis.AnalysisVulnerabilities, 0)
	})

	t.Run("should add error on analysis when parsing invalid output", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "1243567890")
		analysis := new(analysis.Analysis)

		cfg := config.New()

		dockerAPIControllerMock := testutil.NewDockerMock()
		dockerAPIControllerMock.On("SetAnalysisID")
		dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("invalid output", nil)

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

		formatter := NewFormatter(service)
		formatter.StartAnalysis("")

		assert.True(t, analysis.HasErrors(), "Expected errors on analysis")
	})

	t.Run("should not run nancy tool because not exists environment", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "")
		analysis := new(analysis.Analysis)

		cfg := config.New()

		dockerAPIControllerMock := testutil.NewDockerMock()
		dockerAPIControllerMock.On("SetAnalysisID")
		dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(outputRateLimit, nil)

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

		formatter := NewFormatter(service)
		formatter.StartAnalysis("")

		assert.False(t, analysis.HasErrors(), "Expected errors on analysis")
	})

	t.Run("should add error on analysis when output return rate limit requests", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "1243567890")
		analysis := new(analysis.Analysis)

		cfg := config.New()

		dockerAPIControllerMock := testutil.NewDockerMock()
		dockerAPIControllerMock.On("SetAnalysisID")
		dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(outputRateLimit, nil)

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

		formatter := NewFormatter(service)
		formatter.StartAnalysis("")

		assert.True(t, analysis.HasErrors(), "Expected errors on analysis")
		assert.Contains(t, analysis.Errors, messages.MsgErrorNancyRateLimit)
	})

	t.Run("should add error on analysis when something went wrong executing container", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "1243567890")
		analysis := new(analysis.Analysis)

		dockerAPIControllerMock := testutil.NewDockerMock()
		dockerAPIControllerMock.On("SetAnalysisID")
		dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("", errors.New("test"))

		cfg := config.New()

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

		formatter := NewFormatter(service)
		formatter.StartAnalysis("")

		assert.True(t, analysis.HasErrors(), "Expected errors on analysis")
	})

	t.Run("should not execute tool because it's ignored", func(t *testing.T) {
		_ = os.Setenv("GITHUB_TOKEN", "1243567890")
		analysis := new(analysis.Analysis)

		dockerAPIControllerMock := testutil.NewDockerMock()

		cfg := config.New()
		cfg.ToolsConfig = toolsconfig.ToolsConfig{
			tools.Nancy: toolsconfig.Config{
				IsToIgnore: true,
			},
		}

		service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)
		formatter := NewFormatter(service)

		formatter.StartAnalysis("")
	})
}