...

Source file src/oss.terrastruct.com/d2/d2ir/import_test.go

Documentation: oss.terrastruct.com/d2/d2ir

     1  package d2ir_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"oss.terrastruct.com/util-go/assert"
     7  
     8  	"oss.terrastruct.com/d2/d2ir"
     9  )
    10  
    11  func testCompileImports(t *testing.T) {
    12  	t.Parallel()
    13  
    14  	tca := []testCase{
    15  		{
    16  			name: "value",
    17  			run: func(t testing.TB) {
    18  				m, err := compileFS(t, "index.d2", map[string]string{
    19  					"index.d2": "x: @x.d2",
    20  					"x.d2": `shape: circle
    21  label: meow`,
    22  				})
    23  				assert.Success(t, err)
    24  				assertQuery(t, m, 3, 0, nil, "")
    25  				assertQuery(t, m, 2, 0, nil, "x")
    26  				assertQuery(t, m, 0, 0, "circle", "x.shape")
    27  				assertQuery(t, m, 0, 0, "meow", "x.label")
    28  			},
    29  		},
    30  		{
    31  			name: "nested/map",
    32  			run: func(t testing.TB) {
    33  				m, err := compileFS(t, "index.d2", map[string]string{
    34  					"index.d2": "x: @x.y",
    35  					"x.d2": `y: {
    36  	shape: circle
    37  	label: meow
    38  }`,
    39  				})
    40  				assert.Success(t, err)
    41  				assertQuery(t, m, 3, 0, nil, "")
    42  				assertQuery(t, m, 2, 0, nil, "x")
    43  				assertQuery(t, m, 0, 0, "circle", "x.shape")
    44  				assertQuery(t, m, 0, 0, "meow", "x.label")
    45  			},
    46  		},
    47  		{
    48  			name: "nested/array",
    49  			run: func(t testing.TB) {
    50  				m, err := compileFS(t, "index.d2", map[string]string{
    51  					"index.d2": "x: @x.y",
    52  					"x.d2":     `y: [1, 2]`,
    53  				})
    54  				assert.Success(t, err)
    55  				assertQuery(t, m, 1, 0, nil, "")
    56  				x := assertQuery(t, m, 0, 0, nil, "x")
    57  				xf, ok := x.(*d2ir.Field)
    58  				assert.True(t, ok)
    59  				assert.Equal(t, `[1, 2]`, xf.Composite.String())
    60  			},
    61  		},
    62  		{
    63  			name: "nested/scalar",
    64  			run: func(t testing.TB) {
    65  				m, err := compileFS(t, "index.d2", map[string]string{
    66  					"index.d2": "x: @x.y",
    67  					"x.d2":     `y: meow`,
    68  				})
    69  				assert.Success(t, err)
    70  				assertQuery(t, m, 1, 0, nil, "")
    71  				assertQuery(t, m, 0, 0, "meow", "x")
    72  			},
    73  		},
    74  		{
    75  			name: "boards",
    76  			run: func(t testing.TB) {
    77  				m, err := compileFS(t, "index.d2", map[string]string{
    78  					"index.d2": `x.link: layers.x; layers: { x: @x }`,
    79  					"x.d2":     `y.link: layers.y; layers: { y: @y }`,
    80  					"y.d2":     `meow`,
    81  				})
    82  				assert.Success(t, err)
    83  				assertQuery(t, m, 0, 0, "root.layers.x", "x.link")
    84  				assertQuery(t, m, 0, 0, "root.layers.x.layers.y", "layers.x.y.link")
    85  			},
    86  		},
    87  		{
    88  			name: "boards-deep",
    89  			run: func(t testing.TB) {
    90  				m, err := compileFS(t, "index.d2", map[string]string{
    91  					"index.d2": `a.link: layers.b; layers: { b: @b }`,
    92  					"b.d2":     `b.link: layers.c; layers: { c: @c }`,
    93  					"c.d2":     `c.link: layers.d; layers: { d: @d }`,
    94  					"d.d2":     `d`,
    95  				})
    96  				assert.Success(t, err)
    97  				assertQuery(t, m, 0, 0, "root.layers.b.layers.c.layers.d", "layers.b.layers.c.c.link")
    98  			},
    99  		},
   100  		{
   101  			name: "steps-inheritence",
   102  			run: func(t testing.TB) {
   103  				m, err := compileFS(t, "index.d2", map[string]string{
   104  					"index.d2": `z; steps: { 1: @x; 2: @y }; scenarios: { x: @x; y: @y }`,
   105  					"x.d2":     `a`,
   106  					"y.d2":     `b`,
   107  				})
   108  				assert.Success(t, err)
   109  				assertQuery(t, m, 2, 0, nil, "scenarios.x")
   110  				assertQuery(t, m, 2, 0, nil, "scenarios.y")
   111  				assertQuery(t, m, 2, 0, nil, "steps.1")
   112  				assertQuery(t, m, 3, 0, nil, "steps.2")
   113  			},
   114  		},
   115  		{
   116  			name: "spread",
   117  			run: func(t testing.TB) {
   118  				m, err := compileFS(t, "index.d2", map[string]string{
   119  					"index.d2": "...@x.d2",
   120  					"x.d2":     "x: wowa",
   121  				})
   122  				assert.Success(t, err)
   123  				assertQuery(t, m, 1, 0, nil, "")
   124  				assertQuery(t, m, 0, 0, "wowa", "x")
   125  			},
   126  		},
   127  		{
   128  			name: "nested/spread",
   129  			run: func(t testing.TB) {
   130  				m, err := compileFS(t, "index.d2", map[string]string{
   131  					"index.d2": "...@x.y",
   132  					"x.d2":     "y: { jon; jan }",
   133  				})
   134  				assert.Success(t, err)
   135  				assertQuery(t, m, 2, 0, nil, "")
   136  				assertQuery(t, m, 0, 0, nil, "jan")
   137  				assertQuery(t, m, 0, 0, nil, "jon")
   138  			},
   139  		},
   140  		{
   141  			name: "nested/spread_primary",
   142  			run: func(t testing.TB) {
   143  				m, err := compileFS(t, "index.d2", map[string]string{
   144  					"index.d2": "q: { ...@x.y }",
   145  					"x.d2":     "y: meow { jon; jan }",
   146  				})
   147  				assert.Success(t, err)
   148  				assertQuery(t, m, 3, 0, nil, "")
   149  				assertQuery(t, m, 2, 0, "meow", "q")
   150  				assertQuery(t, m, 0, 0, nil, "q.jan")
   151  				assertQuery(t, m, 0, 0, nil, "q.jon")
   152  			},
   153  		},
   154  		{
   155  			name: "vars/1",
   156  			run: func(t testing.TB) {
   157  				m, err := compileFS(t, "index.d2", map[string]string{
   158  					"index.d2": "vars: { ...@x }; q: ${meow}",
   159  					"x.d2":     "meow: var replaced",
   160  				})
   161  				assert.Success(t, err)
   162  				assertQuery(t, m, 0, 0, "var replaced", "q")
   163  			},
   164  		},
   165  		{
   166  			name: "vars/2",
   167  			run: func(t testing.TB) {
   168  				m, err := compileFS(t, "index.d2", map[string]string{
   169  					"index.d2": "vars: { x: 1 }; ...@a",
   170  					"a.d2":     "vars: { x: 2 }; hi: ${x}",
   171  				})
   172  				assert.Success(t, err)
   173  				assertQuery(t, m, 0, 0, 2, "hi")
   174  			},
   175  		},
   176  		{
   177  			name: "vars/3",
   178  			run: func(t testing.TB) {
   179  				m, err := compileFS(t, "index.d2", map[string]string{
   180  					"index.d2": "...@a; vars: { x: 1 }; hi: ${x}",
   181  					"a.d2":     "vars: { x: 2 }",
   182  				})
   183  				assert.Success(t, err)
   184  				assertQuery(t, m, 0, 0, 1, "hi")
   185  			},
   186  		},
   187  		{
   188  			name: "pattern-value",
   189  			run: func(t testing.TB) {
   190  				_, err := compileFS(t, "index.d2", map[string]string{
   191  					"index.d2": `userWebsite
   192  userMobile
   193  
   194  user*: @x
   195  `,
   196  					"x.d2": `shape: person
   197  label: meow`,
   198  				})
   199  				assert.Success(t, err)
   200  			},
   201  		},
   202  		{
   203  			name: "merge-arrays",
   204  			run: func(t testing.TB) {
   205  				_, err := compileFS(t, "index.d2", map[string]string{
   206  					"index.d2": `x.class: [a]
   207  ...@d
   208  `,
   209  					"d.d2": `x.class: [b]`,
   210  				})
   211  				assert.Success(t, err)
   212  			},
   213  		},
   214  	}
   215  
   216  	runa(t, tca)
   217  
   218  	t.Run("errors", func(t *testing.T) {
   219  		tca := []testCase{
   220  			{
   221  				name: "not_exist",
   222  				run: func(t testing.TB) {
   223  					_, err := compileFS(t, "index.d2", map[string]string{
   224  						"index.d2": "...@x.d2",
   225  					})
   226  					assert.ErrorString(t, err, `index.d2:1:1: failed to import "x.d2": open x.d2: no such file or directory`)
   227  				},
   228  			},
   229  			{
   230  				name: "escape",
   231  				run: func(t testing.TB) {
   232  					_, err := compileFS(t, "index.d2", map[string]string{
   233  						"index.d2": "...@'./../x.d2'",
   234  					})
   235  					assert.ErrorString(t, err, `index.d2:1:1: failed to import "../x.d2": stat ../x.d2: invalid argument`)
   236  				},
   237  			},
   238  			{
   239  				name: "absolute",
   240  				run: func(t testing.TB) {
   241  					_, err := compileFS(t, "index.d2", map[string]string{
   242  						"index.d2": "...@/x.d2",
   243  					})
   244  					assert.ErrorString(t, err, `index.d2:1:1: import paths must be relative`)
   245  				},
   246  			},
   247  			{
   248  				name: "parse",
   249  				run: func(t testing.TB) {
   250  					_, err := compileFS(t, "index.d2", map[string]string{
   251  						"index.d2": "...@x.d2",
   252  						"x.d2":     "x<><><<>q",
   253  					})
   254  					assert.ErrorString(t, err, `x.d2:1:1: connection missing destination
   255  x.d2:1:4: connection missing source
   256  x.d2:1:4: connection missing destination
   257  x.d2:1:6: connection missing source
   258  x.d2:1:6: connection missing destination
   259  x.d2:1:7: connection missing source`)
   260  				},
   261  			},
   262  			{
   263  				name: "cyclic",
   264  				run: func(t testing.TB) {
   265  					_, err := compileFS(t, "index.d2", map[string]string{
   266  						"index.d2": "...@x",
   267  						"x.d2":     "...@y",
   268  						"y.d2":     "...@q",
   269  						"q.d2":     "...@x",
   270  					})
   271  					assert.ErrorString(t, err, `q.d2:1:1: detected cyclic import chain: x.d2 -> y.d2 -> q.d2 -> x.d2`)
   272  				},
   273  			},
   274  			{
   275  				name: "spread_non_map",
   276  				run: func(t testing.TB) {
   277  					_, err := compileFS(t, "index.d2", map[string]string{
   278  						"index.d2": "...@x.y",
   279  						"x.d2":     "y: meow",
   280  					})
   281  					assert.ErrorString(t, err, `index.d2:1:1: cannot spread import non map into map`)
   282  				},
   283  			},
   284  		}
   285  		runa(t, tca)
   286  	})
   287  }
   288  

View as plain text