github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/lua/rockspec_parser_test.go (about)

     1  package lua
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func Test_parseRockspecData(t *testing.T) {
    12  	tests := []struct {
    13  		name    string
    14  		content string
    15  		wantErr require.ErrorAssertionFunc
    16  	}{
    17  		{
    18  			name: "basic valid content",
    19  			content: `
    20  foo = "bar"
    21  hello = "world"
    22  object = {
    23  	foo = "bar",
    24  	baz = "test",
    25  	nested = {
    26  		lorem = "ipsum"
    27  	}
    28  }
    29  alice = "bob"
    30  `,
    31  		},
    32  		{
    33  			name: "lists",
    34  			content: `
    35  foo = "bar"
    36  list = {"hello", "world" }
    37  `,
    38  		},
    39  		{
    40  			name: "empty list",
    41  			content: `
    42  foo = "bar"
    43  list = {}
    44  `,
    45  		},
    46  		{
    47  			name: "different string delimiters",
    48  			content: `
    49  foo = 'bar'
    50  hello = "world"
    51  `,
    52  		},
    53  		{
    54  
    55  			name: "multiline string",
    56  			content: `
    57  foo = "bar"
    58  multiline = [[
    59  	this is
    60  	a multiline
    61  	string
    62  ]]
    63  `,
    64  		},
    65  		{
    66  			name: "variables",
    67  			content: `
    68  local foo = "bar"
    69  local baz = foo
    70  
    71  hello = baz
    72  `,
    73  		},
    74  		{
    75  			name: "multiple variables in one line",
    76  			content: `
    77  local foo, bar = "hello", "world"
    78  baz = foo
    79  test = bar
    80  `,
    81  		},
    82  		{
    83  			name: "skip expressions",
    84  			content: `
    85  test = (hello == "world") and "foo" or "bar"
    86  baz = "123"
    87  `,
    88  		},
    89  		{
    90  			name: "skip expressions in locals",
    91  			content: `
    92  local var1 = "foo"
    93  local var2 = var1 == "foo" and "true" or ("false")
    94  
    95  foo = "bar"
    96  `,
    97  		},
    98  		{
    99  			name: "concatenation",
   100  			content: `
   101  local foo = "bar"
   102  local baz = "123"
   103  hello = "world"..baz
   104  baz = foo.." "..baz
   105  test = foo .. baz
   106  `,
   107  		},
   108  		{
   109  			name: "complex syntax",
   110  			content: `
   111  foo = "bar"
   112  object = {
   113  	["baz"] = "bar"
   114  }
   115  `,
   116  		},
   117  		{
   118  			name: "content with comment",
   119  			content: `
   120  foo = "bar"
   121  -- this is a comment
   122  object = {
   123  	hello = "world"
   124  	-- this is another comment
   125  }
   126  `,
   127  		},
   128  		{
   129  			name: "content start with comment",
   130  			content: `
   131  foo = "bar"
   132  -- this is a comment
   133  object = {
   134  	-- this is another comment
   135  	hello = "world"
   136  }
   137  `,
   138  		},
   139  		{
   140  			name: "list with comment",
   141  			content: `
   142  list = {
   143  	"foo",
   144  	"bar",
   145  	-- "baz"
   146  	"hello"
   147  }
   148  `,
   149  		},
   150  		{
   151  			name: "skip build section",
   152  			content: `
   153  foo = "bar"
   154  build = {
   155  	a = {
   156  		{
   157  			content
   158  		}
   159  	}
   160  }
   161  bar = "baz"
   162  `,
   163  		},
   164  		{
   165  			name: "skip functions",
   166  			content: `
   167  local function test
   168  	if foo == bar then
   169  		if hello = world then
   170  			blah
   171  		end
   172  	end
   173  end
   174  test = "blah"
   175  `,
   176  		},
   177  		{
   178  			name:    "invalid complex syntax",
   179  			wantErr: require.Error,
   180  			content: `
   181  foo = "bar"
   182  object = {
   183  	["baz" = "bar"
   184  	["hello"] = world
   185  }
   186  `,
   187  		},
   188  		{
   189  			name:    "unterminated block",
   190  			wantErr: require.Error,
   191  			content: `
   192  foo = "bar"
   193  hello = "world"
   194  object = {
   195  `,
   196  		},
   197  		{
   198  			name:    "invalid string content",
   199  			wantErr: require.Error,
   200  			content: `
   201  test = "unfinished
   202  		`,
   203  		},
   204  		{
   205  			name:    "mixed string delimiters",
   206  			wantErr: require.Error,
   207  			content: `
   208  foo = "bar'
   209  `,
   210  		},
   211  		{
   212  			name:    "unterminated multiline string",
   213  			wantErr: require.Error,
   214  			content: `
   215  		foo = "bar"
   216  		hello = "world"
   217  		object = [[
   218  		`,
   219  		},
   220  		{
   221  			name:    "invalid multiline string content",
   222  			wantErr: require.Error,
   223  			content: `
   224  test = [[
   225  	unfinished
   226  		`,
   227  		},
   228  		{
   229  			name:    "list with unterminated comment",
   230  			wantErr: require.Error,
   231  			content: `
   232  list = {
   233  	"foo",
   234  	"bar",
   235  	-`,
   236  		},
   237  		{
   238  			name:    "undefined local",
   239  			wantErr: require.Error,
   240  			content: `
   241  test = hello
   242  		`,
   243  		},
   244  		{
   245  			name:    "unterminated concatenation",
   246  			wantErr: require.Error,
   247  			content: `
   248  local foo = "123"
   249  hello = foo..  `,
   250  		},
   251  	}
   252  	for _, test := range tests {
   253  		t.Run(test.name, func(t *testing.T) {
   254  			value, err := parseRockspecData(bytes.NewReader([]byte(test.content)))
   255  
   256  			if test.wantErr == nil {
   257  				require.NoError(t, err)
   258  			} else {
   259  				test.wantErr(t, err)
   260  			}
   261  
   262  			assert.IsType(t, rockspec{}, value)
   263  		})
   264  	}
   265  }