2 # Copyright (C) 2006-2010, Parrot Foundation.
7 t/pmc/namepspace.t - test NameSpace PMC
11 % prove t/pmc/namespace.t
15 Tests the NameSpace PMC. Some things that it tests specifically:
19 =item* Creating new NameSpace PMCs
21 =item* Verify that things which are supposed to return a NameSpace actually
24 =item* Various forms of get_global opcode
26 =item* Finding and calling Subs which are stored in the NameSpace
28 =item* Methods on the NameSpace PMC
30 =item* Building NameSpace hierarchies on the fly
36 Items that need to be tested according to PDD21, or the current source code
41 =item* methods: add_sub, del_sub, del_var, del_namespace
43 =item* Typed and Untyped interfaces
45 =item* Subclassing NameSpace (If it's possible)
49 Although NameSpace.'export_to'() is used in test_more.pir.
58 .include 'test_more.pir'
61 create_namespace_pmc()
62 verify_namespace_type()
64 keyed_namespace_lookup()
66 get_sub_from_namespace_hash()
67 access_sub_in_namespace()
68 get_namespace_from_sub()
69 build_namespaces_at_runtime()
71 anon_function_namespace()
77 # L<PDD21/Namespace PMC API/=head4 Untyped Interface>
78 .sub 'create_namespace_pmc'
80 $P0 = new ['NameSpace']
81 ok(1, "Create new Namespace PMC")
84 ok(0, "Could not create Namespace PMC")
89 .sub 'verify_namespace_type'
90 $P0 = get_global "Foo"
92 is($S0, "NameSpace", "A NameSpace is a NameSpace")
95 $P0 = get_root_namespace
97 is($S0, "NameSpace", "Root NameSpace is a NameSpace")
99 # While we're here. Prove that the root namespace stringifies to ""
101 is($S0, "", "Root NameSpace stringifies to empty string")
106 is($S0, "NameSpace", "::parrot NameSpace is a NameSpace")
108 # get_namespace with no args
111 is($S0, "NameSpace", "Current NameSpace is a NameSpace")
113 # Prove that HLL namespace names are mangled to lower-case
114 $P0 = get_root_namespace ["MyHLL"]
116 is($I0, 1, "HLL NameSpace names are stored lowercase")
118 $P0 = get_root_namespace ["myhll"]
120 is($I0, 0, "HLL NameSpaces are name-mangled lowercase")
122 # Get an HLL namespace and verify that it's a NameSpace PMC
123 $P0 = get_root_namespace ["myhll"]
125 is($S0, "NameSpace", "HLL NameSpaces are NameSpaces too")
129 .sub 'get_namespace_class'
130 # First, prove that we don't have a class until it's created
131 $P0 = get_global "Foo"
134 is($I0, 1, "NameSpace doesn't have a Class till it's created")
136 # Can create a new class from a NameSpace
139 is($I0, 0, "Create Class from NameSpace")
141 # New Class is a Class
143 is($S0, "Class", "get_class on a NameSpace returns a Class")
145 # Class has same name as namespace
148 is($S0, $S1, "Class has same name as NameSpace")
150 # Now, we do have a class
153 is($I0, 0, "get_class on a NameSpace returns something")
155 # Create object from class from NameSpace
158 ok(1, "Can create a new object from a namespace")
161 ok(0, "Cannot create a new object from a namespace")
165 # Object from Class from NameSpace has right type
167 is($S0, "Foo", "Object created from class has name of NameSpace")
171 .sub keyed_namespace_lookup
172 # Tests to verify behavior of TT #1449
173 $P0 = get_root_namespace
176 $P1 = $P0["parrot";"Foo";"Bar"]
178 is($I0, 0, "can lookup nested namespace by Key")
179 # TODO: Get the function from this namespace and call it to verify we have
183 $P1 = new ['ResizableStringArray']
190 is($I0, 0, "can lookup nested namespace by RSA")
191 # TODO: Get the function from this namespace and call it to verify we have
198 is($I0, 0, "can lookup namespace by string")
200 is($I0, 0, "can lookup namespace by string")
201 # TODO: Get the function from this namespace and call it to verify we have
206 .sub 'get_global_opcode'
209 $P0 = get_global "baz"
211 is($S0, "", "Can get_global a .sub")
214 ok(0, "Cannot get_global a .sub")
220 $P0 = get_global ["Foo"], "baz"
222 is($S0, "Foo", "Get Sub from NameSpace")
225 ok(0, "Cannot get Sub from NameSpace Foo")
231 $P0 = get_global ["Foo";"Bar"], "baz"
233 is($S0, "Foo::Bar", "Get Sub from nested NameSpace")
236 ok(0, "Cannot get Sub from NameSpace Foo::Bar")
241 throws_substring( <<'CODE', 'Null PMC access in invoke', 'Invoking a non-existent sub')
243 $P0 = get_global ["Foo"], "SUB_THAT_DOES_NOT_EXIST"
249 # this used to behave differently from the previous case.
250 throws_substring( <<'CODE', 'Null PMC access in invoke', 'Invoking a non-existent sub')
252 $P0 = get_global ["Foo";"Bar"], "SUB_THAT_DOES_NOT_EXIST"
259 $P0 = get_global [ iso-8859-1:"Fran\x{E7}ois" ], "baz"
261 is($S0, iso-8859-1:"Fran\x{E7}ois", "Found sub in ISO-8859 NameSpace")
264 ok(0, "Cannot find sub in ISO-8859 NameSpace")
270 $P0 = get_global [ "Foo";iso-8859-1:"Fran\x{E7}ois" ], "baz"
272 is($S0, iso-8859-1:"Foo::Fran\x{E7}ois", "Found sub in nested ISO-8859 NameSpace")
275 ok(0, "Cannot find sub in ISO-8859 NameSpace")
281 $P0 = get_global [ unicode:"Fran\x{00E7}ois" ], "baz"
283 is($I0, 0, "Find Sub in an ISO-8859-1 NameSpace looked up by a Unicode name")
285 is($S0, iso-8859-1:"Fran\x{E7}ois", "ISO-8859 NameSpace with Unicode name")
288 ok(0, "Cannot find ISO-8859 NameSpace using Unicode name")
294 $P0 = get_global [ unicode:"\x{20AC}uros" ], "baz"
296 is($S0, unicode:"\x{20AC}uros", "Found sub in Unicode NameSpace")
299 ok(0, "Cannot find sub in Unicode NameSpace")
305 $P0 = get_global [ "Foo";unicode:"\x{20AC}uros" ], "baz"
307 is($S0, unicode:"Foo::\x{20AC}uros", "Found sub in nested Unicode NameSpace")
310 ok(0, "Cannot find sub in nested Unicode NameSpace")
316 .sub 'get_sub_from_namespace_hash'
317 #See that a NameSpace does Hash
318 $P0 = get_global "Foo"
319 $I0 = does $P0, 'hash'
320 ok($I0, "Namespace does hash")
322 # Use a hash key to get a Sub in a namespace
325 is($S0, "Foo", "Get the Sub from the NameSpace as a Hash")
327 # Use hash keys to get Subs and nested NameSpaces in NameSpaces
331 is($S0, "Foo::Bar", "Get the Sub from the nested NameSpace as a Hash")
333 # Use nested keys to access nested NameSpaces
334 $P1 = $P0[ "Bar";"baz" ]
336 is($S0, "Foo::Bar", "Get Sub from nested NameSpace with multi-key")
338 # Alias a namespace and access it by Key
340 set_global "TopBar", $P1
341 $P2 = get_global ["TopBar"], "baz"
342 is($S0, "Foo::Bar", "Alias namespace")
344 # Get nested NameSpace with ISO-8859 name
345 $P1 = $P0[ iso-8859-1:"Fran\x{E7}ois" ]
348 is($S0, iso-8859-1:"Foo::Fran\x{E7}ois", "Hash-get nested ISO-8859 NameSpace")
350 $P1 = $P0[ iso-8859-1:"Fran\x{E7}ois";"baz" ]
352 is($S0, iso-8859-1:"Foo::Fran\x{E7}ois", "Hash-get nested ISO-8859 NameSpace Sub")
354 $P0 = get_global iso-8859-1:"Fran\x{E7}ois"
357 is($S0, iso-8859-1:"Fran\x{E7}ois", "Hash-get ISO-8859 NameSpace")
360 .sub 'access_sub_in_namespace'
361 # Direct access of sub that does exist in current namespace
363 $P0 = get_global "baz"
365 is($S0, $S1, "Direct and Indirect Sub calls")
367 # Direct access of sub that doesn't exist in current namespace
370 ok(0, "Directly called a sub that doesn't exist")
373 ok(1, "Can't direct call a sub that doesn't exist")
378 .sub 'get_namespace_from_sub'
379 # root namespace is "parrot"
380 $P0 = get_global "baz"
381 $P1 = $P0."get_namespace"()
383 is($S0, "parrot", "Get the root namespace from a sub in the root namespace")
385 # Get an explicit namespace
386 $P0 = get_global ["Foo"], "baz"
387 $P1 = $P0."get_namespace"()
389 is($S0, "Foo", "Get the namespace from a Sub in the NameSpace")
391 # Get namespace from the current sub
392 .include 'interpinfo.pasm'
393 $P0 = interpinfo .INTERPINFO_CURRENT_SUB
394 $P1 = $P0."get_namespace"()
396 is($S0, "parrot", "Get namespace from current sub")
398 # Now get the current sub again
399 $P2 = $P1["get_namespace_from_sub"]
401 is($S0, "Sub", "Get the current sub from namespace from current sub")
404 .sub 'build_namespaces_at_runtime'
405 $P0 = get_root_namespace
407 $P3 = new ['NameSpace']
409 $P2 = $P3.'get_name'()
411 is($S0, "parrot::Temp1", "Add a NameSpace with a given name")
413 # test VTABLE_get_string while we are here
415 is($S0, "parrot", "get_string on HLL NameSpace")
418 is($S0, "Temp1", "get_string on NameSpace")
421 .sub 'hll_namespaces'
422 # Fetch HLL Global using an RSA. Current HLL == parrot
423 $P4 = new ['FixedStringArray']
426 $P0 = get_hll_namespace $P4
427 $P2 = $P0.'get_name'()
429 is($S0, "parrot::Foo", "get_hll_namespace_p")
431 # Get an HLL namespace using a key. Current HLL == parrot
432 $P2 = get_hll_namespace ["Foo"]
433 $P2 = $P2.'get_name'()
435 is($S0, "parrot::Foo", "get_hll_namespace_kc")
437 # Get a sub from an HLL Namespace using a key. Current HLL == parrot
438 $P0 = get_hll_namespace ["Foo"]
441 is($S0, "Foo", "get a Sub from a HLL namespace")
443 # find something an a different .HLL
445 $P0 = get_root_namespace ["myhll"]
448 is($S0, "MyHLL", "Found Sub in HLL namespace by key")
451 ok(0, "Cannot find sub in HLL NameSpace by key")
455 # get_root_namespace won't return something not a namespace
456 $P0 = get_root_namespace ["myhll";"baz"]
458 is($I0, 1, "get_root_namespace only returns NameSpace PMCs")
461 .sub 'anon_function_namespace'
464 .namespace ["anon_test_internal_ns"]
465 .sub anon_test_internal :main :anon
474 is($S0, "NameSpace", "get_namespace from anon sub")
475 $P3 = $P2.'get_name'()
477 is($S0, "parrot::anon_test_internal_ns", "get_namespace name from anon sub")
480 .sub 'find_name_opcode'
483 .namespace ['pugs';'main']
486 $P0 = find_name "&say"
504 is($I0, 1, "find_name sub with sigil in namespace")
507 .sub 'namespace_methods'
510 # make_namespace returns the existing namespace if it exists
511 $P1 = $P0.'make_namespace'("Foo")
514 is($S0, "Foo", "make_namespace does not overwrite existing NS")
516 # First we don't have it...
517 $P1 = $P0["NewNamespace1"]
519 is($I0, 1, "something that doesn't exist really doesn't")
522 $P1 = $P0.'make_namespace'("NewNamespace1")
525 is($I0, 1, "make_namespace also creates new namespaces")
527 $P1 = new ["NameSpace"]
528 $P0.'add_namespace'("NewNamespace2", $P1)
529 $P2 = $P0["NewNamespace2"]
530 is($P1, $P2, "add_namespace adds a new namespace")
536 $P0.'add_var'("My_Integer", $P1)
537 $P2 = $P0["My_Integer"]
538 is($P1, $P2, "add_var adds a variable to the namespace")
540 # We've already tested NameSpace."get_name" elsewhere in this file
542 $P1 = $P0.'find_namespace'("Foo")
545 is($S0, "Foo", "find_namespace finds a .namespace constant")
547 $P1 = $P0.'find_namespace'("NewNamespace1")
549 is($S0, "NameSpace", "find_namespace finds a namespace added at runtime")
551 $P1 = $P0.'find_sub'("baz")
553 is($S0, "", "find_sub finds a sub like it should")
555 $P1 = $P0.'find_sub'("NewNamespace1")
557 is($I0, 1, "find_sub won't find a non-sub")
559 $P1 = $P0.'find_sub'("DOESNT EXIST")
561 is($I0, 1, "find_sub won't find something that doesn't exist")
563 $P1 = $P0.'find_var'("My_Integer")
565 is($I0, 25, "find_var finds a variable we've saved in a namespace")
567 $P1 = $P0.'find_var'("ALSO DOESNT EXIST")
569 is($I0, 1, "find_var won't find something that doesn't exist")
571 $P1 = $P0.'find_var'("baz")
573 is($S0, "Sub", "find_var also finds subs")
575 is($S0, "", "find_var finds the correct sub")
577 # Test del_namespace. Test that it deletes an existing namespace, and that
578 # it won't delete something that isn't a namespace
580 # Test del_sub. Test that it deletes an existing sub and that it
581 # won't delete something that isn't a sub
583 # Test del_var. It will delete any type of thing
586 .sub 'export_to_method'
587 .local string errormsg, description
589 errormsg = "destination namespace not specified"
590 description = "export_to() Null NameSpace"
591 throws_substring(<<"CODE", errormsg, description)
593 .local pmc nsa, nsb, ar
595 ar = new ['ResizableStringArray']
598 nsb = get_namespace ['Foo']
599 nsb.'export_to'(nsa, ar)
603 errormsg = "exporting default object set not yet implemented"
604 description = 'export_to() with null exports default object set !!!UNSPECIFIED!!!'
605 throws_substring(<<'CODE', errormsg, description)
607 .local pmc nsa, nsb, ar
611 nsb = get_namespace ['Foo']
612 nsb.'export_to'(nsa, ar)
617 errormsg = "exporting default object set not yet implemented"
618 description = 'export_to() with empty array exports default object set !!!UNSPECIFIED!!!'
619 throws_substring(<<'CODE', errormsg, description)
621 .local pmc nsa, nsb, ar
623 ar = new ['ResizableStringArray']
625 nsb = get_namespace ['Foo']
626 nsb.'export_to'(nsa, ar)
630 errormsg = "exporting default object set not yet implemented"
631 description = 'export_to() with empty hash exports default object set !!!UNSPECIFIED!!!'
632 throws_substring(<<'CODE', errormsg, description)
634 .local pmc nsa, nsb, ar
638 nsb = get_namespace ['Foo']
639 nsb.'export_to'(nsa, ar)
643 # Things to add: successful export_to with non-empty array, successful
644 # export_to with non-empty hash. both of these things across HLL boundaries
648 ##### TEST NAMESPACES AND FUNCTIONS #####
649 # These functions and namespaces are used for the tests above
651 # The current namespace
663 # NameSpace "Foo";"Bar". Nested namespace
664 .namespace ["Foo";"Bar"]
669 # Namespace "Foo";"Bar";"Baz". Nested namespace
670 .namespace ["Foo";"Bar";"Baz"]
672 .return("Foo::Bar::Baz")
675 # Namespace specified in ISO-8859-1
676 .namespace [ iso-8859-1:"Fran\x{E7}ois" ]
678 .return(iso-8859-1:"Fran\x{E7}ois")
681 # Nested namespace specified in ISO-8859
682 .namespace [ "Foo"; iso-8859-1:"Fran\x{E7}ois" ]
684 .return(iso-8859-1:"Foo::Fran\x{E7}ois")
687 # Namesace specified in Unicode
688 .namespace [ unicode:"\x{20AC}uros" ]
690 .return(unicode:"\x{20AC}uros")
693 # Nested namespace specified in Unicode
694 .namespace [ "Foo";unicode:"\x{20AC}uros" ]
696 .return(unicode:"Foo::\x{20AC}uros")
708 # vim: expandtab shiftwidth=4 ft=pir: