github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/licensing/expression/parser_test.go (about)

     1  package expression
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestParse(t *testing.T) {
    12  	tests := []struct {
    13  		name    string
    14  		input   string
    15  		want    Expression
    16  		wantStr string
    17  		wantErr string
    18  	}{
    19  		{
    20  			name:  "single license",
    21  			input: "Public Domain",
    22  			want: SimpleExpr{
    23  				license: "Public Domain",
    24  			},
    25  			wantStr: "Public Domain",
    26  		},
    27  		{
    28  			name:  "tag:value license",
    29  			input: "DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2",
    30  			want: SimpleExpr{
    31  				license: "DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2",
    32  			},
    33  			wantStr: "DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2",
    34  		},
    35  		{
    36  			name:  "symbols",
    37  			input: "Public ._-+",
    38  			want: SimpleExpr{
    39  				license: "Public ._-",
    40  				hasPlus: true,
    41  			},
    42  			wantStr: "Public ._-+",
    43  		},
    44  		{
    45  			name:  "multi licenses",
    46  			input: "Public Domain AND ( GPLv2+ or AFL ) AND LGPLv2+ with distribution exceptions",
    47  			want: CompoundExpr{
    48  				left: CompoundExpr{
    49  					left: SimpleExpr{
    50  						license: "Public Domain",
    51  					},
    52  					conjunction: Token{
    53  						token:   AND,
    54  						literal: "AND",
    55  					},
    56  					right: CompoundExpr{
    57  						left: SimpleExpr{
    58  							license: "GPLv2",
    59  							hasPlus: true,
    60  						},
    61  						conjunction: Token{
    62  							token:   OR,
    63  							literal: "or",
    64  						},
    65  						right: SimpleExpr{
    66  							license: "AFL",
    67  						},
    68  					},
    69  				},
    70  				conjunction: Token{
    71  					token:   AND,
    72  					literal: "AND",
    73  				},
    74  				right: CompoundExpr{
    75  					left: SimpleExpr{
    76  						license: "LGPLv2",
    77  						hasPlus: true,
    78  					},
    79  					conjunction: Token{
    80  						token:   WITH,
    81  						literal: "with",
    82  					},
    83  					right: SimpleExpr{
    84  						license: "distribution exceptions",
    85  					},
    86  				},
    87  			},
    88  			wantStr: "Public Domain AND (GPLv2+ or AFL) AND LGPLv2+ with distribution exceptions",
    89  		},
    90  		{
    91  			name:  "nested licenses",
    92  			input: "Public Domain AND ( GPLv2+ or AFL AND ( CC0 or LGPL1.0) )",
    93  			want: CompoundExpr{
    94  				left: SimpleExpr{
    95  					license: "Public Domain",
    96  				},
    97  				conjunction: Token{
    98  					token:   AND,
    99  					literal: "AND",
   100  				},
   101  				right: CompoundExpr{
   102  					left: SimpleExpr{
   103  						license: "GPLv2",
   104  						hasPlus: true,
   105  					},
   106  					conjunction: Token{
   107  						token:   OR,
   108  						literal: "or",
   109  					},
   110  					right: CompoundExpr{
   111  						left: SimpleExpr{
   112  							license: "AFL",
   113  						},
   114  						conjunction: Token{
   115  							token:   AND,
   116  							literal: "AND",
   117  						},
   118  						right: CompoundExpr{
   119  							left: SimpleExpr{
   120  								license: "CC0",
   121  							},
   122  							conjunction: Token{
   123  								token:   OR,
   124  								literal: "or",
   125  							},
   126  							right: SimpleExpr{
   127  								license: "LGPL1.0",
   128  							},
   129  						},
   130  					},
   131  				},
   132  			},
   133  			wantStr: "Public Domain AND (GPLv2+ or AFL AND (CC0 or LGPL1.0))",
   134  		},
   135  		{
   136  			name:    "bad path close bracket not found",
   137  			input:   "Public Domain AND ( GPLv2+ ",
   138  			wantErr: "syntax error",
   139  		},
   140  	}
   141  	for _, tt := range tests {
   142  		t.Run(tt.name, func(t *testing.T) {
   143  			l := NewLexer(strings.NewReader(tt.input))
   144  			ret := yyParse(l)
   145  			err := l.Err()
   146  			if tt.wantErr != "" {
   147  				assert.Equal(t, ret, 1)
   148  				assert.ErrorContains(t, err, tt.wantErr)
   149  				return
   150  			}
   151  			require.NoError(t, err)
   152  			assert.Equal(t, tt.want, l.result)
   153  			assert.Equal(t, tt.wantStr, l.result.String())
   154  		})
   155  	}
   156  }