code: def test_function_basics():
      # Test init fail
      assert_raises(TypeError, Function)  # no args
      assert_raises(ValueError, Function, 3)  # need string
  
      # Test init success 1
      fun = Function("void main(){}")
      assert_equal(fun.name, "main")
      assert len(fun.template_vars) == 0
  
      # Test init success with template vars
      fun = Function("void main(){$foo; $bar;}")
      assert_equal(fun.name, "main")
      assert len(fun.template_vars) == 2
      assert_in("foo", fun.template_vars)
  
      # Test that `var in fun` syntax works as well
      assert "foo" in fun
      assert "bar" in fun
      assert "baz" not in fun
  
      assert_in("bar", fun.template_vars)
  
      # Test setting verbatim expressions
      assert_raises(
          KeyError, fun.__setitem__, "bla", "33"
      )  # no such template
      fun["foo"] = "33"
      fun["bar"] = "bla bla"
      assert_is(type(fun["foo"]), TextExpression)
      assert_equal(fun["foo"].expression(None), "33")
      assert_is(type(fun["bar"]), TextExpression)
      assert_equal(fun["bar"].expression(None), "bla bla")
  
      # Test setting call expressions
      fun = Function(
          "void main(){\n$foo;\n$bar;\n$spam(XX);\n$eggs(YY);\n}"
      )
      trans = Function("float transform_scale(float x) {return x+1.0;}")
      assert_raises(TypeError, trans)  # requires 1 arg
      assert_raises(TypeError, trans, "1", "2")
      fun["foo"] = trans("2")
      fun["bar"] = trans("3")
      fun["spam"] = trans
      fun["eggs"] = trans
      #
      for name in ["foo", "bar"]:
          assert_is(type(fun[name]), FunctionCall)
          assert_equal(fun[name].function, trans)
          assert_in(trans, fun.dependencies())
      for name in ["spam", "eggs"]:
          assert_equal(fun[name], trans)
  
      #
      text = fun.compile()
      assert_in("\ntransform_scale(2);\n", text)
      assert_in("\ntransform_scale(3);\n", text)
      assert_in("\ntransform_scale(XX);\n", text)
      assert_in("\ntransform_scale(YY);\n", text)
  
      # test pre/post assignments
      fun = Function("void main() {some stuff;}")
      fun["pre"] = "__pre__"
      fun["post"] = "__post__"
      text = fun.compile()
      assert (
          text
          == "void main() {\n    __pre__\nsome stuff;\n    __post__\n}\n"
      )
  
      # Test variable expressions
      fun = Function("void main(){$foo; $bar;}")
      fun["foo"] = Variable("uniform float bla")
      fun["bar"] = Variable("attribute float bla")
      assert_is(type(fun["foo"]), Variable)
      assert_is(type(fun["bar"]), Variable)
      assert_in(fun["foo"], fun.dependencies())
      assert_in(fun["bar"], fun.dependencies())
  
      # Test special variables
      fun = Function("void main(){$foo; $bar;}")
      variable = Variable("attribute vec3 v_pos")
      varying = Variable("varying vec3 color")
      # These do not work due to index
      assert_raises(TypeError, fun.__setitem__, 3, 3)  # not a string
      assert_raises(
          KeyError, fun.__setitem__, "xxx", 3
      )  # unknown template var
      assert_raises(
          TypeError, fun.__setitem__, variable, 3
      )  # only varyings
      # These work
      fun["gl_PointSize"] = "3.0"
      fun[varying] = variable
      # And getting works
      assert_equal(fun["gl_PointSize"].text, "3.0")
      assert_equal(fun[varying], variable)
  
file_path: vispy/vispy/visuals/shaders/tests/test_function.py
imports: from vispy.visuals.shaders import Function, MainFunction, Variable, Varying, FunctionChain, StatementList
  from vispy.visuals.shaders.expression import FunctionCall, TextExpression
  from vispy.testing import assert_in, assert_not_in, assert_is, run_tests_if_main, assert_raises, assert_equal
label_desc: Use image node_id 6 for calling a global function with example usage: test_function_basics() without return types