...

Source file src/github.com/bazelbuild/buildtools/warn/types_test.go

Documentation: github.com/bazelbuild/buildtools/warn

     1  /*
     2  Copyright 2020 Google LLC
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      https://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package warn
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"strings"
    23  	"testing"
    24  
    25  	"github.com/bazelbuild/buildtools/build"
    26  	"github.com/bazelbuild/buildtools/testutils"
    27  )
    28  
    29  func checkTypes(t *testing.T, input, output string) {
    30  	input = strings.TrimLeft(input, "\n")
    31  	f, err := build.Parse("test.bzl", []byte(input))
    32  	if err != nil {
    33  		t.Fatalf("%v", err)
    34  	}
    35  	types := DetectTypes(f)
    36  
    37  	var edit func(expr build.Expr, stack []build.Expr) build.Expr
    38  	edit = func(expr build.Expr, stack []build.Expr) build.Expr {
    39  		t, ok := types[expr]
    40  		if !ok {
    41  			return nil
    42  		}
    43  		// Traverse the node's children before modifying this node.
    44  		build.EditChildren(expr, edit)
    45  		start, _ := expr.Span()
    46  		return &build.Ident{
    47  			Name:    fmt.Sprintf("%s:<%s>", t, build.FormatString(expr)),
    48  			NamePos: start,
    49  		}
    50  	}
    51  
    52  	build.Edit(f, edit)
    53  
    54  	want := []byte(strings.TrimLeft(output, "\n"))
    55  	have := build.FormatWithoutRewriting(f)
    56  	if !bytes.Equal(have, want) {
    57  		t.Errorf("detected types incorrectly: diff shows -expected, +ours")
    58  		testutils.Tdiff(t, want, have)
    59  	}
    60  }
    61  
    62  func TestTypes(t *testing.T) {
    63  	checkTypes(t, `
    64  b = True
    65  b2 = bool("hello")
    66  i = 3
    67  i2 = int(1.2)
    68  f = 1.2
    69  f2 = float(3)
    70  s = "string"
    71  s2 = s
    72  s3 = str(42)
    73  d = {}
    74  d2 = {foo: bar}
    75  d3 = dict(**foo)
    76  d4 = {k: v for k, v in foo}
    77  dep = depset(items=[s, d])
    78  foo = bar
    79  `, `
    80  b = bool:<True>
    81  b2 = bool:<bool(string:<"hello">)>
    82  i = int:<3>
    83  i2 = int:<int(float:<1.2>)>
    84  f = float:<1.2>
    85  f2 = float:<float(int:<3>)>
    86  s = string:<"string">
    87  s2 = string:<s>
    88  s3 = string:<str(int:<42>)>
    89  d = dict:<{}>
    90  d2 = dict:<{foo: bar}>
    91  d3 = dict:<dict(**foo)>
    92  d4 = dict:<{k: v for k, v in foo}>
    93  dep = depset:<depset(items = list:<[
    94      string:<s>,
    95      dict:<d>,
    96  ]>)>
    97  foo = bar
    98  `)
    99  }
   100  
   101  func TestScopesFunction(t *testing.T) {
   102  	checkTypes(t, `
   103  s = "string"
   104  
   105  def f():
   106      s1 = s
   107  
   108  def g():
   109      s2 = s1
   110  `, `
   111  s = string:<"string">
   112  
   113  def f():
   114      s1 = string:<s>
   115  
   116  def g():
   117      s2 = s1
   118  `)
   119  }
   120  
   121  func TestScopesParameters(t *testing.T) {
   122  	checkTypes(t, `
   123  x = 3
   124  y = 4
   125  z = 5
   126  
   127  foo(y = "bar")
   128  foo(x, y = bar(z = z), t + z)
   129  
   130  
   131  def f(z = "bar"):
   132      return z
   133  
   134  bar(x, y, z)
   135  `, `
   136  x = int:<3>
   137  y = int:<4>
   138  z = int:<5>
   139  
   140  foo(y = string:<"bar">)
   141  foo(int:<x>, y = bar(z = int:<z>), int:<t + int:<z>>)
   142  
   143  def f(z = string:<"bar">):
   144      return string:<z>
   145  
   146  bar(int:<x>, int:<y>, int:<z>)
   147  `)
   148  }
   149  
   150  func TestBinaryOperators(t *testing.T) {
   151  	checkTypes(t, `
   152  i = 1
   153  d = {}
   154  s = depset()
   155  
   156  i - foo
   157  foo - i
   158  
   159  d + bar
   160  bar + d
   161  
   162  s | baz
   163  baz | s
   164  `, `
   165  i = int:<1>
   166  d = dict:<{}>
   167  s = depset:<depset()>
   168  
   169  int:<int:<i> - foo>
   170  int:<foo - int:<i>>
   171  
   172  dict:<dict:<d> + bar>
   173  dict:<bar + dict:<d>>
   174  
   175  depset:<depset:<s> | baz>
   176  depset:<baz | depset:<s>>
   177  `)
   178  }
   179  
   180  func TestPercentOperator(t *testing.T) {
   181  	checkTypes(t, `
   182  n = 3
   183  s = "foo"
   184  
   185  foo % n
   186  foo % s
   187  foo % bar
   188  
   189  n % foo
   190  s % foo
   191  
   192  s %= foo
   193  n %= foo
   194  
   195  baz = unknown
   196  baz %= s
   197  baz
   198  
   199  boq = unknown
   200  boq %= n
   201  boq
   202  `, `
   203  n = int:<3>
   204  s = string:<"foo">
   205  
   206  foo % int:<n>
   207  string:<foo % string:<s>>
   208  foo % bar
   209  
   210  int:<int:<n> % foo>
   211  string:<string:<s> % foo>
   212  
   213  string:<s> %= foo
   214  int:<n> %= foo
   215  
   216  baz = unknown
   217  baz %= string:<s>
   218  string:<baz>
   219  
   220  boq = unknown
   221  boq %= int:<n>
   222  boq
   223  `)
   224  }
   225  
   226  func TestContext(t *testing.T) {
   227  	checkTypes(t, `
   228  def foobar(ctx, foo, bar):
   229      ctx
   230      ctx.actions
   231      ctx.actions.args()
   232  
   233      actions = ctx.actions
   234      not_args = actions.args
   235      args = actions.args()
   236      args
   237  `, `
   238  def foobar(ctx:<ctx>, foo, bar):
   239      ctx:<ctx>
   240      ctx.actions:<ctx:<ctx>.actions>
   241      ctx.actions.args:<ctx.actions:<ctx:<ctx>.actions>.args()>
   242  
   243      actions = ctx.actions:<ctx:<ctx>.actions>
   244      not_args = ctx.actions:<actions>.args
   245      args = ctx.actions.args:<ctx.actions:<actions>.args()>
   246      ctx.actions.args:<args>
   247  `)
   248  }
   249  
   250  func TestContextFalse(t *testing.T) {
   251  	checkTypes(t, `
   252  def foobar(foo, bar):
   253      ctx
   254      ctx.actions
   255      ctx.actions.args()
   256  `, `
   257  def foobar(foo, bar):
   258      ctx
   259      ctx.actions
   260      ctx.actions.args()
   261  `)
   262  }
   263  

View as plain text