github.com/cheshirekow/buildtools@v0.0.0-20200224190056-5d637702fe81/warn/warn_docstring_test.go (about)

     1  package warn
     2  
     3  import "testing"
     4  
     5  func TestModuleDocstring(t *testing.T) {
     6  	checkFindings(t, "module-docstring", ``,
     7  		[]string{},
     8  		scopeBzl|scopeDefault)
     9  
    10  	checkFindings(t, "module-docstring", `
    11  # empty file`,
    12  		[]string{},
    13  		scopeBzl|scopeDefault)
    14  
    15  	checkFindings(t, "module-docstring", `
    16  """This is the module"""
    17  
    18  load("foo", "bar")
    19  
    20  bar()`,
    21  		[]string{},
    22  		scopeBzl|scopeDefault)
    23  
    24  	checkFindings(t, "module-docstring", `
    25  load("foo", "bar")
    26  
    27  """This is the module"""
    28  
    29  bar()`,
    30  		[]string{":1: The file has no module docstring."},
    31  		scopeBzl|scopeDefault)
    32  
    33  	checkFindings(t, "module-docstring", `
    34  # comment
    35  
    36  # comment
    37  """This is the module"""
    38  
    39  load("foo", "bar")
    40  
    41  bar()`,
    42  		[]string{},
    43  		scopeBzl|scopeDefault)
    44  
    45  	checkFindings(t, "module-docstring", `
    46  # comment
    47  
    48  load("foo", "bar")
    49  
    50  # comment
    51  """This is the module"""
    52  
    53  bar()`,
    54  		[]string{":3: The file has no module docstring."},
    55  		scopeBzl|scopeDefault)
    56  
    57  	checkFindings(t, "module-docstring", `
    58  def foo(bar):
    59    if bar:
    60      f()
    61    return g()`,
    62  		[]string{":1: The file has no module docstring."},
    63  		scopeBzl|scopeDefault)
    64  }
    65  
    66  func TestFunctionDocstringExists(t *testing.T) {
    67  	checkFindings(t, "function-docstring", `
    68  def f(x):
    69     # short function
    70     return x
    71  `,
    72  		[]string{},
    73  		scopeEverywhere)
    74  
    75  	checkFindings(t, "function-docstring", `
    76  def f(x):
    77     """Short function with a docstring"""
    78     return x
    79  `,
    80  		[]string{},
    81  		scopeEverywhere)
    82  
    83  	checkFindings(t, "function-docstring", `
    84  def f(x):
    85     # long function
    86     x += 1
    87     x *= 2
    88     x /= 3
    89     x -= 4
    90     x %= 5
    91     return x
    92  `,
    93  		[]string{":1: The function \"f\" has no docstring."},
    94  		scopeEverywhere)
    95  
    96  	checkFindings(t, "function-docstring", `
    97  def _f(x):
    98     # long private function
    99     x += 1
   100     x *= 2
   101     x /= 3
   102     x -= 4
   103     x %= 5
   104     return x
   105  `,
   106  		[]string{},
   107  		scopeEverywhere)
   108  }
   109  
   110  func TestFunctionDocstringHeader(t *testing.T) {
   111  	checkFindings(t, "function-docstring-header", `
   112  def f():
   113     """This is a function.
   114     this is the description
   115     """
   116     pass
   117     pass
   118     pass
   119     pass
   120     pass
   121  `,
   122  		[]string{`2: The docstring for the function "f" should start with a one-line summary.`},
   123  		scopeEverywhere)
   124  
   125  	checkFindings(t, "function-docstring-header", `
   126  	def _f(x):
   127  	  """Long private function
   128  	  with a docstring"""
   129  	  x += 1
   130  	  x *= 2
   131  	  x /= 3
   132  	  x -= 4
   133  	  x %= 5
   134  	  return x
   135  	`,
   136  		[]string{
   137  			`:2: The docstring for the function "_f" should start with a one-line summary.`,
   138  		},
   139  		scopeEverywhere)
   140  
   141  	checkFindings(t, "function-docstring-header", `
   142  	def f(x):
   143  	  """Long function with a docstring
   144  
   145  		Docstring
   146  		body
   147  		"""
   148  	  x += 1
   149  	  x *= 2
   150  	  x /= 3
   151  	  x -= 4
   152  	  x %= 5
   153  	  return x
   154  	`,
   155  		[]string{},
   156  		scopeEverywhere)
   157  
   158  	checkFindings(t, "function-docstring-header", `
   159  def f():
   160     """
   161  
   162     This is a function.
   163  
   164     This is a
   165     multiline description"""
   166     pass
   167     pass
   168     pass
   169     pass
   170     pass
   171  `,
   172  		[]string{},
   173  		scopeEverywhere)
   174  }
   175  
   176  func TestFunctionDocstringArgs(t *testing.T) {
   177  	checkFindings(t, "function-docstring-args", `
   178  def f(x):
   179     """This is a function.
   180  
   181     Documented here:
   182     http://example.com
   183  
   184     Args:
   185       x: something, as described at
   186         http://example.com
   187  
   188     Returns:
   189       something, as described at
   190       https://example.com
   191     """
   192     pass
   193     pass
   194     pass
   195     pass
   196     pass
   197     return x
   198  `,
   199  		[]string{},
   200  		scopeEverywhere)
   201  
   202  	checkFindings(t, "function-docstring-args", `
   203  def f(x):
   204     """This is a function.
   205  
   206     Args:
   207       x: something
   208     """
   209     passf
   210     pass
   211     pass
   212     pass
   213     pass
   214  `,
   215  		[]string{},
   216  		scopeEverywhere)
   217  
   218  	checkFindings(t, "function-docstring-args", `
   219  def f(x, y):
   220    """Short function with a docstring
   221  
   222    Arguments:
   223      x: smth
   224    """
   225    return x + y
   226  `,
   227  		[]string{
   228  			`2: Argument "y" is not documented.`,
   229  			`4: Prefer "Args:" to "Arguments:" when documenting function arguments.`,
   230  		},
   231  		scopeEverywhere)
   232  
   233  	checkFindings(t, "function-docstring-args", `
   234  def _f(x, y):
   235    """Long private function
   236    
   237    Args:
   238      x: something
   239      z: something
   240    """
   241    x *= 2
   242    x /= 3
   243    x -= 4
   244    x %= 5
   245    return x
   246  `,
   247  		[]string{
   248  			`:2: Argument "y" is not documented.`,
   249  			`:6: Argument "z" is documented but doesn't exist in the function signature.`,
   250  		},
   251  		scopeEverywhere)
   252  
   253  	checkFindings(t, "function-docstring-args", `
   254  def f(x, y):
   255     """This is a function.
   256  
   257     Arguments:
   258       x: something
   259          y: something (this is in fact the description of x continued)
   260       z: something else
   261  
   262     Returns:
   263       None
   264     """
   265     pass
   266     pass
   267     pass
   268     pass
   269     pass
   270  `,
   271  		[]string{
   272  			`2: Argument "y" is not documented.`,
   273  			`4: Prefer "Args:" to "Arguments:" when documenting function arguments.`,
   274  			`7: Argument "z" is documented but doesn't exist in the function signature.`,
   275  		}, scopeEverywhere)
   276  
   277  	checkFindings(t, "function-docstring-args", `
   278  def my_function(x, y, z = None, *args, **kwargs):
   279     """This is a function.
   280     """
   281     pass
   282     pass
   283     pass
   284     pass
   285     pass
   286  `,
   287  		[]string{
   288  			`2: Arguments "x", "y", "z", "*args", "**kwargs" are not documented.
   289  
   290  If the documentation for the arguments exists but is not recognized by Buildifier
   291  make sure it follows the line "Args:" which has the same indentation as the opening """,
   292  and the argument description starts with "<argument_name>:" and indented with at least
   293  one (preferably two) space more than "Args:", for example:
   294  
   295      def my_function(x):
   296          """Function description.
   297  
   298          Args:
   299            x: argument description, can be
   300              multiline with additional indentation.
   301          """`,
   302  		},
   303  		scopeEverywhere)
   304  
   305  	checkFindings(t, "function-docstring-args", `
   306  def f(x, y, z = None, *args, **kwargs):
   307     """This is a function.
   308  
   309     Args:
   310      x: x
   311      y (deprecated, mutable): y
   312      z: z
   313      *args: the args
   314      **kwargs: the kwargs
   315     """
   316     pass
   317     pass
   318     pass
   319     pass
   320     pass
   321  `,
   322  		[]string{},
   323  		scopeEverywhere)
   324  
   325  	checkFindings(t, "function-docstring-args", `
   326  def f(x, *, y, z = None):
   327     """This is a function.
   328  
   329     Args:
   330      x: x
   331      y: y
   332      z: z
   333     """
   334     pass
   335  `,
   336  		[]string{},
   337  		scopeEverywhere)
   338  
   339  	checkFindings(t, "function-docstring-args", `
   340  def f(x, *, y, z = None):
   341     """This is a function.
   342  
   343     Args:
   344      x: x
   345      *: a separator
   346      y: y
   347      : argument without a name
   348      z: z
   349     """
   350     pass
   351  `,
   352  		[]string{
   353  			`6: Argument "*" is documented but doesn't exist in the function signature.`,
   354  			`8: Argument "" is documented but doesn't exist in the function signature.`,
   355  		},
   356  		scopeEverywhere)
   357  
   358  	checkFindings(t, "function-docstring-args", `
   359  def f(x):
   360     """
   361     This is a function.
   362  
   363     Args:
   364  
   365       The function signature is extremely complicated
   366  
   367       x: something
   368     Returns:
   369       nothing
   370     """
   371     pass
   372     pass
   373     pass
   374     pass
   375     pass
   376     return None
   377  `,
   378  		[]string{},
   379  		scopeEverywhere)
   380  
   381  	checkFindings(t, "function-docstring-args", `
   382  def f(foobar, *bar, **baz):
   383    """Some function
   384    
   385    Args:
   386      foobar: something
   387      foo: something
   388      bar: something
   389      baz: something
   390    """
   391    pass
   392  `,
   393  		[]string{
   394  			`:2: Arguments "*bar", "**baz" are not documented.`,
   395  			`:6: Argument "foo" is documented but doesn't exist in the function signature.`,
   396  			`:7: Argument "bar" is documented but doesn't exist in the function signature. Do you mean "*bar"?`,
   397  			`:8: Argument "baz" is documented but doesn't exist in the function signature. Do you mean "**baz"?`,
   398  		},
   399  		scopeEverywhere)
   400  }
   401  
   402  func TestFunctionDocstringReturn(t *testing.T) {
   403  	checkFindings(t, "function-docstring-return", `
   404  def f(x):
   405     """This is a function.
   406  
   407     Args:
   408       x: something
   409  
   410     Returns:
   411       something
   412     """
   413     pass
   414     pass
   415     pass
   416     pass
   417     pass
   418     return x
   419  `,
   420  		[]string{},
   421  		scopeEverywhere)
   422  
   423  	checkFindings(t, "function-docstring-return", `
   424  def f(x):
   425     """This is a function.
   426  
   427     Args:
   428       x: something
   429     """
   430     pass
   431     pass
   432     pass
   433     pass
   434     pass
   435  `,
   436  		[]string{},
   437  		scopeEverywhere)
   438  
   439  	checkFindings(t, "function-docstring-return", `
   440  def f(x):
   441     """This is a function.
   442  
   443     Args:
   444       x: something
   445     """
   446     pass
   447     pass
   448     pass
   449     pass
   450     pass
   451     return x
   452  `,
   453  		[]string{`2: Return value of "f" is not documented.`},
   454  		scopeEverywhere)
   455  
   456  	checkFindings(t, "function-docstring-return", `
   457  def f(x):
   458     """This is a function.
   459  
   460     Args:
   461       x: something
   462     """
   463     pass
   464     pass
   465     pass
   466     pass
   467     pass
   468     if foo:
   469       return
   470     else:
   471       return x
   472  `,
   473  		[]string{`2: Return value of "f" is not documented.`},
   474  		scopeEverywhere)
   475  }