github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/pkg/platform/runtime/buildexpression/buildexpression_test.go (about)

     1  package buildexpression
     2  
     3  import (
     4  	"path/filepath"
     5  	"reflect"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/ActiveState/cli/internal/environment"
    10  	"github.com/ActiveState/cli/internal/fileutils"
    11  	"github.com/ActiveState/cli/pkg/platform/api/buildplanner/types"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestNew(t *testing.T) {
    16  	type args struct {
    17  		filename string
    18  	}
    19  	tests := []struct {
    20  		name    string
    21  		args    args
    22  		wantErr bool
    23  	}{
    24  		{
    25  			name: "basic",
    26  			args: args{
    27  				filename: "buildexpression.json",
    28  			},
    29  			wantErr: false,
    30  		},
    31  		{
    32  			name: "complex",
    33  			args: args{
    34  				filename: "buildexpression-complex.json",
    35  			},
    36  			wantErr: false,
    37  		},
    38  		{
    39  			name: "unordered",
    40  			args: args{
    41  				filename: "buildexpression-unordered.json",
    42  			},
    43  			wantErr: false,
    44  		},
    45  		{
    46  			name: "installer",
    47  			args: args{
    48  				filename: "buildexpression-installer.json",
    49  			},
    50  			wantErr: false,
    51  		},
    52  		{
    53  			name: "installer-complex",
    54  			args: args{
    55  				filename: "buildexpression-installer-complex.json",
    56  			},
    57  			wantErr: false,
    58  		},
    59  		{
    60  			name: "nested",
    61  			args: args{
    62  				filename: "buildexpression-nested.json",
    63  			},
    64  			wantErr: false,
    65  		},
    66  		{
    67  			name: "alternate",
    68  			args: args{
    69  				filename: "buildexpression-alternate.json",
    70  			},
    71  			wantErr: false,
    72  		},
    73  	}
    74  	for _, tt := range tests {
    75  		t.Run(tt.name, func(t *testing.T) {
    76  			wd, err := environment.GetRootPath()
    77  			assert.NoError(t, err)
    78  
    79  			data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "platform", "runtime", "buildexpression", "testdata", tt.args.filename))
    80  			assert.NoError(t, err)
    81  
    82  			_, err = New(data)
    83  			if (err != nil) != tt.wantErr {
    84  				t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr)
    85  				return
    86  			}
    87  		})
    88  	}
    89  }
    90  
    91  func TestBuildExpression_Requirements(t *testing.T) {
    92  	type args struct {
    93  		filename string
    94  	}
    95  	tests := []struct {
    96  		name    string
    97  		args    args
    98  		want    []types.Requirement
    99  		wantErr bool
   100  	}{
   101  		{
   102  			name: "basic",
   103  			args: args{
   104  				filename: "buildexpression.json",
   105  			},
   106  			want: []types.Requirement{
   107  				{
   108  					Name:      "jinja2-time",
   109  					Namespace: "language/python",
   110  				},
   111  				{
   112  					Name:      "jupyter-contrib-nbextensions",
   113  					Namespace: "language/python",
   114  				},
   115  				{
   116  					Name:      "python",
   117  					Namespace: "language",
   118  					VersionRequirement: []types.VersionRequirement{
   119  						map[string]string{
   120  							"comparator": string(types.ComparatorEQ),
   121  							"version":    "3.10.10",
   122  						},
   123  					},
   124  				},
   125  				{
   126  					Name:      "copier",
   127  					Namespace: "language/python",
   128  				},
   129  				{
   130  					Name:      "jupyterlab",
   131  					Namespace: "language/python",
   132  				},
   133  			},
   134  			wantErr: false,
   135  		},
   136  		{
   137  			name: "installer-complex",
   138  			args: args{
   139  				filename: "buildexpression-installer-complex.json",
   140  			},
   141  			want: []types.Requirement{
   142  				{
   143  					Name:      "perl",
   144  					Namespace: "language",
   145  					VersionRequirement: []types.VersionRequirement{
   146  						map[string]string{
   147  							"comparator": string(types.ComparatorEQ),
   148  							"version":    "5.36.0",
   149  						},
   150  					},
   151  				},
   152  			},
   153  			wantErr: false,
   154  		},
   155  		{
   156  			name: "alternate",
   157  			args: args{
   158  				filename: "buildexpression-alternate.json",
   159  			},
   160  			want: []types.Requirement{
   161  				{
   162  					Name:      "Path-Tiny",
   163  					Namespace: "language/perl",
   164  				},
   165  				{
   166  					Name:      "perl",
   167  					Namespace: "language",
   168  					VersionRequirement: []types.VersionRequirement{
   169  						map[string]string{
   170  							"comparator": string(types.ComparatorEQ),
   171  							"version":    "5.36.1",
   172  						},
   173  					},
   174  				},
   175  			},
   176  			wantErr: false,
   177  		},
   178  	}
   179  	for _, tt := range tests {
   180  		t.Run(tt.name, func(t *testing.T) {
   181  			wd, err := environment.GetRootPath()
   182  			assert.NoError(t, err)
   183  
   184  			data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "platform", "runtime", "buildexpression", "testdata", tt.args.filename))
   185  			assert.NoError(t, err)
   186  
   187  			bx, err := New(data)
   188  			assert.NoError(t, err)
   189  
   190  			got, err := bx.Requirements()
   191  			assert.NoError(t, err)
   192  			if !reflect.DeepEqual(got, tt.want) {
   193  				t.Errorf("BuildExpression.Requirements() = %v, want %v", got, tt.want)
   194  			}
   195  		})
   196  	}
   197  }
   198  
   199  func TestBuildExpression_Update(t *testing.T) {
   200  	type args struct {
   201  		requirement types.Requirement
   202  		operation   types.Operation
   203  		filename    string
   204  	}
   205  	tests := []struct {
   206  		name    string
   207  		args    args
   208  		want    []types.Requirement
   209  		wantErr bool
   210  	}{
   211  		{
   212  			name: "add",
   213  			args: args{
   214  				requirement: types.Requirement{
   215  					Name:      "requests",
   216  					Namespace: "language/python",
   217  				},
   218  				operation: types.OperationAdded,
   219  				filename:  "buildexpression.json",
   220  			},
   221  			want: []types.Requirement{
   222  				{
   223  					Name:      "jinja2-time",
   224  					Namespace: "language/python",
   225  				},
   226  				{
   227  					Name:      "jupyter-contrib-nbextensions",
   228  					Namespace: "language/python",
   229  				},
   230  				{
   231  					Name:      "python",
   232  					Namespace: "language",
   233  					VersionRequirement: []types.VersionRequirement{
   234  						map[string]string{
   235  							"comparator": string(types.ComparatorEQ),
   236  							"version":    "3.10.10",
   237  						},
   238  					},
   239  				},
   240  				{
   241  					Name:      "copier",
   242  					Namespace: "language/python",
   243  				},
   244  				{
   245  					Name:      "jupyterlab",
   246  					Namespace: "language/python",
   247  				},
   248  				{
   249  					Name:      "requests",
   250  					Namespace: "language/python",
   251  				},
   252  			},
   253  			wantErr: false,
   254  		},
   255  		{
   256  			name: "remove",
   257  			args: args{
   258  				requirement: types.Requirement{
   259  					Name:      "jupyterlab",
   260  					Namespace: "language/python",
   261  				},
   262  				operation: types.OperationRemoved,
   263  				filename:  "buildexpression.json",
   264  			},
   265  			want: []types.Requirement{
   266  				{
   267  					Name:      "jinja2-time",
   268  					Namespace: "language/python",
   269  				},
   270  				{
   271  					Name:      "jupyter-contrib-nbextensions",
   272  					Namespace: "language/python",
   273  				},
   274  				{
   275  					Name:      "python",
   276  					Namespace: "language",
   277  					VersionRequirement: []types.VersionRequirement{
   278  						map[string]string{
   279  							"comparator": string(types.ComparatorEQ),
   280  							"version":    "3.10.10",
   281  						},
   282  					},
   283  				},
   284  				{
   285  					Name:      "copier",
   286  					Namespace: "language/python",
   287  				},
   288  			},
   289  			wantErr: false,
   290  		},
   291  		{
   292  			name: "update",
   293  			args: args{
   294  				requirement: types.Requirement{
   295  					Name:      "python",
   296  					Namespace: "language",
   297  					VersionRequirement: []types.VersionRequirement{
   298  						map[string]string{
   299  							"comparator": string(types.ComparatorEQ),
   300  							"version":    "3.11.0",
   301  						},
   302  					},
   303  				},
   304  				operation: types.OperationUpdated,
   305  				filename:  "buildexpression.json",
   306  			},
   307  			want: []types.Requirement{
   308  				{
   309  					Name:      "jinja2-time",
   310  					Namespace: "language/python",
   311  				},
   312  				{
   313  					Name:      "jupyter-contrib-nbextensions",
   314  					Namespace: "language/python",
   315  				},
   316  				{
   317  					Name:      "python",
   318  					Namespace: "language",
   319  					VersionRequirement: []types.VersionRequirement{
   320  						map[string]string{
   321  							"comparator": string(types.ComparatorEQ),
   322  							"version":    "3.11.0",
   323  						},
   324  					},
   325  				},
   326  				{
   327  					Name:      "copier",
   328  					Namespace: "language/python",
   329  				},
   330  				{
   331  					Name:      "jupyterlab",
   332  					Namespace: "language/python",
   333  				},
   334  			},
   335  			wantErr: false,
   336  		},
   337  		{
   338  			name: "remove not existing",
   339  			args: args{
   340  				requirement: types.Requirement{
   341  					Name:      "requests",
   342  					Namespace: "language/python",
   343  				},
   344  				operation: types.OperationRemoved,
   345  				filename:  "buildexpression.json",
   346  			},
   347  			want: []types.Requirement{
   348  				{
   349  					Name:      "jinja2-time",
   350  					Namespace: "language/python",
   351  				},
   352  				{
   353  					Name:      "jupyter-contrib-nbextensions",
   354  					Namespace: "language/python",
   355  				},
   356  				{
   357  					Name:      "python",
   358  					Namespace: "language",
   359  					VersionRequirement: []types.VersionRequirement{
   360  						map[string]string{
   361  							"comparator": string(types.ComparatorEQ),
   362  							"version":    "3.10.10",
   363  						},
   364  					},
   365  				},
   366  				{
   367  					Name:      "copier",
   368  					Namespace: "language/python",
   369  				},
   370  				{
   371  					Name:      "jupyterlab",
   372  					Namespace: "language/python",
   373  				},
   374  			},
   375  			wantErr: true,
   376  		},
   377  		{
   378  			name: "add-installer-complex",
   379  			args: args{
   380  				requirement: types.Requirement{
   381  					Name:      "JSON",
   382  					Namespace: "language/perl",
   383  				},
   384  				operation: types.OperationAdded,
   385  				filename:  "buildexpression-installer-complex.json",
   386  			},
   387  			want: []types.Requirement{
   388  				{
   389  					Name:      "perl",
   390  					Namespace: "language",
   391  					VersionRequirement: []types.VersionRequirement{
   392  						map[string]string{
   393  							"comparator": string(types.ComparatorEQ),
   394  							"version":    "5.36.0",
   395  						},
   396  					},
   397  				},
   398  				{
   399  					Name:      "JSON",
   400  					Namespace: "language/perl",
   401  				},
   402  			},
   403  			wantErr: false,
   404  		},
   405  		{
   406  			name: "add-alternate",
   407  			args: args{
   408  				requirement: types.Requirement{
   409  					Name:      "JSON",
   410  					Namespace: "language/perl",
   411  				},
   412  				operation: types.OperationAdded,
   413  				filename:  "buildexpression-alternate.json",
   414  			},
   415  			want: []types.Requirement{
   416  				{
   417  					Name:      "Path-Tiny",
   418  					Namespace: "language/perl",
   419  				},
   420  				{
   421  					Name:      "perl",
   422  					Namespace: "language",
   423  					VersionRequirement: []types.VersionRequirement{
   424  						map[string]string{
   425  							"comparator": string(types.ComparatorEQ),
   426  							"version":    "5.36.1",
   427  						},
   428  					},
   429  				},
   430  				{
   431  					Name:      "JSON",
   432  					Namespace: "language/perl",
   433  				},
   434  			},
   435  			wantErr: false,
   436  		},
   437  	}
   438  	for _, tt := range tests {
   439  		t.Run(tt.name, func(t *testing.T) {
   440  			wd, err := environment.GetRootPath()
   441  			assert.NoError(t, err)
   442  
   443  			data, err := fileutils.ReadFile(filepath.Join(wd, "pkg", "platform", "runtime", "buildexpression", "testdata", tt.args.filename))
   444  			assert.NoError(t, err)
   445  
   446  			bx, err := New(data)
   447  			assert.NoError(t, err)
   448  
   449  			err = bx.UpdateRequirement(tt.args.operation, tt.args.requirement)
   450  			if err != nil {
   451  				if tt.wantErr {
   452  					return
   453  				}
   454  
   455  				t.Errorf("BuildExpression.Update() error = %v, wantErr %v", err, tt.wantErr)
   456  				return
   457  			}
   458  
   459  			got, err := bx.Requirements()
   460  			assert.NoError(t, err)
   461  
   462  			sort.Slice(got, func(i, j int) bool {
   463  				return got[i].Name < got[j].Name
   464  			})
   465  
   466  			sort.Slice(tt.want, func(i, j int) bool {
   467  				return tt.want[i].Name < tt.want[j].Name
   468  			})
   469  
   470  			if !reflect.DeepEqual(got, tt.want) {
   471  				t.Errorf("BuildExpression.Requirements() = %v, want %v", got, tt.want)
   472  			}
   473  		})
   474  	}
   475  }