github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/generator/helper/helper_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package helper
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/SAP/jenkins-library/pkg/config"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  func configOpenFileMock(name string) (io.ReadCloser, error) {
    19  	meta1 := `metadata:
    20    name: testStep
    21    aliases:
    22      - name: testStepAlias
    23        deprecated: true
    24    description: Test description
    25    longDescription: |
    26      Long Test description
    27  spec:
    28    outputs:
    29      resources:
    30        - name: reports
    31          type: reports
    32          params:
    33            - filePattern: "test-report_*.json"
    34              subFolder: "sonarExecuteScan"
    35            - filePattern: "report1"
    36              type: general
    37        - name: commonPipelineEnvironment
    38          type: piperEnvironment
    39          params:
    40            - name: artifactVersion
    41            - name: git/commitId
    42            - name: git/headCommitId
    43            - name: git/branch
    44            - name: custom/customList
    45              type: "[]string"
    46        - name: influxTest
    47          type: influx
    48          params:
    49            - name: m1
    50              fields:
    51                - name: f1
    52              tags:
    53                - name: t1
    54    inputs:
    55      resources:
    56        - name: stashName
    57          type: stash
    58      params:
    59        - name: param0
    60          aliases: 
    61          - name: oldparam0
    62          type: string
    63          description: param0 description
    64          default: val0
    65          scope:
    66          - GENERAL
    67          - PARAMETERS
    68          mandatory: true
    69        - name: param1
    70          aliases: 
    71          - name: oldparam1
    72            deprecated: true
    73          type: string
    74          description: param1 description
    75          scope:
    76          - PARAMETERS
    77          possibleValues:
    78          - value1
    79          - value2
    80          - value3
    81          deprecationMessage: use param3 instead
    82        - name: param2
    83          type: string
    84          description: param2 description
    85          scope:
    86          - PARAMETERS
    87          mandatoryIf:
    88          - name: param1
    89            value: value1
    90        - name: param3
    91          type: string
    92          description: param3 description
    93          scope:
    94          - PARAMETERS
    95          possibleValues:
    96          - value1
    97          - value2
    98          - value3
    99          mandatoryIf:
   100          - name: param1
   101            value: value1
   102          - name: param2
   103            value: value2
   104  `
   105  	var r string
   106  	switch name {
   107  	case "testStep.yaml":
   108  		r = meta1
   109  	default:
   110  		r = ""
   111  	}
   112  	return io.NopCloser(strings.NewReader(r)), nil
   113  }
   114  
   115  var files map[string][]byte
   116  
   117  func writeFileMock(filename string, data []byte, perm os.FileMode) error {
   118  	if files == nil {
   119  		files = make(map[string][]byte)
   120  	}
   121  	files[filename] = data
   122  	return nil
   123  }
   124  
   125  func TestProcessMetaFiles(t *testing.T) {
   126  
   127  	stepHelperData := StepHelperData{configOpenFileMock, writeFileMock, ""}
   128  	ProcessMetaFiles([]string{"testStep.yaml"}, "./cmd", stepHelperData)
   129  
   130  	t.Run("step code", func(t *testing.T) {
   131  		goldenFilePath := filepath.Join("testdata", t.Name()+"_generated.golden")
   132  		expected, err := os.ReadFile(goldenFilePath)
   133  		if err != nil {
   134  			t.Fatalf("failed reading %v", goldenFilePath)
   135  		}
   136  		resultFilePath := filepath.Join("cmd", "testStep_generated.go")
   137  		assert.Equal(t, string(expected), string(files[resultFilePath]))
   138  		//t.Log(string(files[resultFilePath]))
   139  	})
   140  
   141  	t.Run("test code", func(t *testing.T) {
   142  		goldenFilePath := filepath.Join("testdata", t.Name()+"_generated.golden")
   143  		expected, err := os.ReadFile(goldenFilePath)
   144  		if err != nil {
   145  			t.Fatalf("failed reading %v", goldenFilePath)
   146  		}
   147  		resultFilePath := filepath.Join("cmd", "testStep_generated_test.go")
   148  		assert.Equal(t, string(expected), string(files[resultFilePath]))
   149  	})
   150  
   151  	t.Run("custom step code", func(t *testing.T) {
   152  		stepHelperData = StepHelperData{configOpenFileMock, writeFileMock, "piperOsCmd"}
   153  		ProcessMetaFiles([]string{"testStep.yaml"}, "./cmd", stepHelperData)
   154  
   155  		goldenFilePath := filepath.Join("testdata", t.Name()+"_generated.golden")
   156  		expected, err := os.ReadFile(goldenFilePath)
   157  		if err != nil {
   158  			t.Fatalf("failed reading %v", goldenFilePath)
   159  		}
   160  		resultFilePath := filepath.Join("cmd", "testStep_generated.go")
   161  		assert.Equal(t, string(expected), string(files[resultFilePath]))
   162  		//t.Log(string(files[resultFilePath]))
   163  	})
   164  }
   165  
   166  func TestSetDefaultParameters(t *testing.T) {
   167  	t.Run("success case", func(t *testing.T) {
   168  		sliceVals := []string{"val4_1", "val4_2"}
   169  		stringSliceDefault := make([]interface{}, len(sliceVals))
   170  		for i, v := range sliceVals {
   171  			stringSliceDefault[i] = v
   172  		}
   173  		stepData := config.StepData{
   174  			Spec: config.StepSpec{
   175  				Inputs: config.StepInputs{
   176  					Parameters: []config.StepParameters{
   177  						{Name: "param0", Type: "string", Default: "val0"},
   178  						{Name: "param1", Type: "string"},
   179  						{Name: "param2", Type: "bool", Default: true},
   180  						{Name: "param3", Type: "bool"},
   181  						{Name: "param4", Type: "[]string", Default: stringSliceDefault},
   182  						{Name: "param5", Type: "[]string"},
   183  						{Name: "param6", Type: "int"},
   184  						{Name: "param7", Type: "int", Default: 1},
   185  					},
   186  				},
   187  			},
   188  		}
   189  
   190  		expected := []string{
   191  			"`val0`",
   192  			"os.Getenv(\"PIPER_param1\")",
   193  			"true",
   194  			"false",
   195  			"[]string{`val4_1`, `val4_2`}",
   196  			"[]string{}",
   197  			"0",
   198  			"1",
   199  		}
   200  
   201  		osImport, err := setDefaultParameters(&stepData)
   202  
   203  		assert.NoError(t, err, "error occurred but none expected")
   204  
   205  		assert.Equal(t, true, osImport, "import of os package required")
   206  
   207  		for k, v := range expected {
   208  			assert.Equal(t, v, stepData.Spec.Inputs.Parameters[k].Default, fmt.Sprintf("default not correct for parameter %v", k))
   209  		}
   210  	})
   211  
   212  	t.Run("error case", func(t *testing.T) {
   213  		stepData := []config.StepData{
   214  			{
   215  				Spec: config.StepSpec{
   216  					Inputs: config.StepInputs{
   217  						Parameters: []config.StepParameters{
   218  							{Name: "param0", Type: "n/a", Default: 10},
   219  							{Name: "param1", Type: "n/a"},
   220  						},
   221  					},
   222  				},
   223  			},
   224  			{
   225  				Spec: config.StepSpec{
   226  					Inputs: config.StepInputs{
   227  						Parameters: []config.StepParameters{
   228  							{Name: "param1", Type: "n/a"},
   229  						},
   230  					},
   231  				},
   232  			},
   233  		}
   234  
   235  		for k, v := range stepData {
   236  			_, err := setDefaultParameters(&v)
   237  			assert.Error(t, err, fmt.Sprintf("error expected but none occurred for parameter %v", k))
   238  		}
   239  	})
   240  }
   241  
   242  func TestGetStepInfo(t *testing.T) {
   243  
   244  	stepData := config.StepData{
   245  		Metadata: config.StepMetadata{
   246  			Name:            "testStep",
   247  			Description:     "Test description",
   248  			LongDescription: "Long Test description",
   249  		},
   250  		Spec: config.StepSpec{
   251  			Inputs: config.StepInputs{
   252  				Parameters: []config.StepParameters{
   253  					{Name: "param0", Scope: []string{"GENERAL"}, Type: "string", Default: "test"},
   254  				},
   255  			},
   256  		},
   257  	}
   258  
   259  	myStepInfo, err := getStepInfo(&stepData, true, "")
   260  
   261  	assert.NoError(t, err)
   262  
   263  	assert.Equal(t, "testStep", myStepInfo.StepName, "StepName incorrect")
   264  	assert.Equal(t, "TestStepCommand", myStepInfo.CobraCmdFuncName, "CobraCmdFuncName incorrect")
   265  	assert.Equal(t, "createTestStepCmd", myStepInfo.CreateCmdVar, "CreateCmdVar incorrect")
   266  	assert.Equal(t, "Test description", myStepInfo.Short, "Short incorrect")
   267  	assert.Equal(t, "Long Test description", myStepInfo.Long, "Long incorrect")
   268  	assert.Equal(t, stepData.Spec.Inputs.Parameters, myStepInfo.StepParameters, "Metadata incorrect")
   269  	assert.Equal(t, "addTestStepFlags", myStepInfo.FlagsFunc, "FlagsFunc incorrect")
   270  	assert.Equal(t, "addTestStepFlags", myStepInfo.FlagsFunc, "FlagsFunc incorrect")
   271  
   272  }
   273  
   274  func TestLongName(t *testing.T) {
   275  	tt := []struct {
   276  		input    string
   277  		expected string
   278  	}{
   279  		{input: "my long name with no ticks", expected: "my long name with no ticks"},
   280  		{input: "my long name with `ticks`", expected: "my long name with ` + \"`\" + `ticks` + \"`\" + `"},
   281  	}
   282  
   283  	for k, v := range tt {
   284  		assert.Equal(t, v.expected, longName(v.input), fmt.Sprintf("wrong long name for run %v", k))
   285  	}
   286  }
   287  
   288  func TestGolangNameTitle(t *testing.T) {
   289  	tt := []struct {
   290  		input    string
   291  		expected string
   292  	}{
   293  		{input: "testApi", expected: "TestAPI"},
   294  		{input: "apiTest", expected: "APITest"},
   295  		{input: "testUrl", expected: "TestURL"},
   296  		{input: "testId", expected: "TestID"},
   297  		{input: "testJson", expected: "TestJSON"},
   298  		{input: "jsonTest", expected: "JSONTest"},
   299  	}
   300  
   301  	for k, v := range tt {
   302  		assert.Equal(t, v.expected, GolangNameTitle(v.input), fmt.Sprintf("wrong golang name for run %v", k))
   303  	}
   304  }
   305  
   306  func TestFlagType(t *testing.T) {
   307  	tt := []struct {
   308  		input    string
   309  		expected string
   310  	}{
   311  		{input: "bool", expected: "BoolVar"},
   312  		{input: "int", expected: "IntVar"},
   313  		{input: "string", expected: "StringVar"},
   314  		{input: "[]string", expected: "StringSliceVar"},
   315  	}
   316  
   317  	for k, v := range tt {
   318  		assert.Equal(t, v.expected, flagType(v.input), fmt.Sprintf("wrong flag type for run %v", k))
   319  	}
   320  }
   321  
   322  func TestGetStringSliceFromInterface(t *testing.T) {
   323  	tt := []struct {
   324  		input    interface{}
   325  		expected []string
   326  	}{
   327  		{input: []interface{}{"Test", 2}, expected: []string{"Test", "2"}},
   328  		{input: "Test", expected: []string{"Test"}},
   329  	}
   330  
   331  	for _, v := range tt {
   332  		assert.Equal(t, v.expected, getStringSliceFromInterface(v.input), "interface conversion failed")
   333  	}
   334  }