| 1 | use PennMUSH; |
|---|
| 2 | use MUSHConnection; |
|---|
| 3 | use TestHarness; |
|---|
| 4 | |
|---|
| 5 | $| = 1; |
|---|
| 6 | |
|---|
| 7 | $mush = PennMUSH->new(); |
|---|
| 8 | # print "MUSH on port ".$mush->{PORT}."\n"; |
|---|
| 9 | # sleep(30); |
|---|
| 10 | $god = $mush->loginGod(); |
|---|
| 11 | |
|---|
| 12 | # First, the basic tests enforcing tree-nature of the attributes. |
|---|
| 13 | # Attrs may not start or end in ` |
|---|
| 14 | test("atree.basic.1", $god, "&foo` me=baz", "not a very good name"); |
|---|
| 15 | test("atree.basic.2", $god, "&`bar me=baz", "not a very good name"); |
|---|
| 16 | # Not even if there's a preexisting branch |
|---|
| 17 | test("atree.basic.3", $god, "&foo me=baz", "Set"); |
|---|
| 18 | test("atree.basic.4", $god, "&foo` me=baz", "not a very good name"); |
|---|
| 19 | # You may not have two ` in a row |
|---|
| 20 | test("atree.basic.5", $god, "&foo``bar me=baz", "not a very good name"); |
|---|
| 21 | # Make a small tree |
|---|
| 22 | test("atree.basic.6", $god, "&foo me=baz", "Set"); |
|---|
| 23 | test("atree.basic.7", $god, "&foo`bar me=baz", "Set"); |
|---|
| 24 | test("atree.basic.8", $god, "&foo`bar`baz me=baz", "Set"); |
|---|
| 25 | # Cannot clear branches with leaves until the leaves are cleared |
|---|
| 26 | test("atree.basic.9", $god, "&foo me", "!Cleared"); |
|---|
| 27 | test("atree.basic.10", $god, "&foo`bar me", "!Cleared"); |
|---|
| 28 | test("atree.basic.11", $god, "&foo`bar`baz me", "Cleared"); |
|---|
| 29 | test("atree.basic.12", $god, "&foo`bar me", "Cleared"); |
|---|
| 30 | test("atree.basic.13", $god, "&foo me", "Cleared"); |
|---|
| 31 | # You can wipe, though. |
|---|
| 32 | test("atree.basic.14", $god, "&foo me=baz", "Set"); |
|---|
| 33 | test("atree.basic.15", $god, "&foo`bar me=baz", "Set"); |
|---|
| 34 | test("atree.basic.16", $god, "&foo`bar`baz me=baz", "Set"); |
|---|
| 35 | test("atree.basic.17", $god, '@wipe me/foo', "wiped"); |
|---|
| 36 | |
|---|
| 37 | # Branch permissions |
|---|
| 38 | # May make a leaf without supporting branch |
|---|
| 39 | test("atree.branch.1", $god, "&foo`bar me=baz", "!You must set FOO first"); |
|---|
| 40 | # And it must make the branch |
|---|
| 41 | test("atree.branch.2", $god, "think hasattr(me, foo)", "1"); |
|---|
| 42 | # Another child should not wipe the previous values |
|---|
| 43 | test("atree.branch.3", $god, "&foo`bar`baz me=baz", "!You must set FOO first"); |
|---|
| 44 | test("atree.branch.4", $god, "think get(me/foo`bar)", "baz"); |
|---|
| 45 | # Clean up again |
|---|
| 46 | test("atree.branch.5", $god, '@wipe me/foo', "wiped"); |
|---|
| 47 | |
|---|
| 48 | # Wildcard attribute matching |
|---|
| 49 | # Rebuild a tree |
|---|
| 50 | test("atree.matching.1", $god, "&foo me=baz", "Set"); |
|---|
| 51 | test("atree.matching.2", $god, "&foo`bar me=baz", "Set"); |
|---|
| 52 | test("atree.matching.3", $god, "&foo`baz me=baz", "Set"); |
|---|
| 53 | test("atree.matching.4", $god, "&foo`bar`baz me=baz", "Set"); |
|---|
| 54 | # Examine should show a ` attribute flag for foo, foo`bar, but not foo`bar`baz |
|---|
| 55 | test("atree.matching.5", $god, "examine me/foo", 'FOO \[.*`\]'); |
|---|
| 56 | test("atree.matching.6", $god, "examine me/foo`bar", 'FOO`BAR \[.*`\]'); |
|---|
| 57 | test("atree.matching.7", $god, "examine me/foo`bar`baz", 'FOO`BAR`BAZ \[[^`]*\]'); |
|---|
| 58 | # Examine doesn't show recursively, by default |
|---|
| 59 | test("atree.matching.8", $god, "examine me", ['FOO \[.*`\]', '!FOO`BAR']); |
|---|
| 60 | # But it will if you ask for it |
|---|
| 61 | test("atree.matching.9", $god, "examine me/**", |
|---|
| 62 | ['FOO \[.*`\]', 'FOO`BAR \[', 'FOO`BAR`BAZ \[[^`]+\]']); |
|---|
| 63 | # If you ask for an attribute, you don't get its children |
|---|
| 64 | test('atree.matching.10', $god, 'examine me/FOO', |
|---|
| 65 | ['FOO \[.*`\]', '!FOO`BAR \[', '!FOO`BAR`BAZ \[[^`]+\]']); |
|---|
| 66 | # You have to ask for the children |
|---|
| 67 | test('atree.matching.11', $god, 'examine me/FOO`', |
|---|
| 68 | ['!FOO \[.*`\]', 'FOO`BAR \[', 'FOO`BAZ \[', '!FOO`BAR`BAZ \[[^`]+\]']); |
|---|
| 69 | test('atree.matching.12', $god, 'examine me/FOO`BAR`', |
|---|
| 70 | ['!FOO \[.*`\]', '!FOO`BAR \[', '!FOO`BAZ \[', 'FOO`BAR`BAZ \[[^`]+\]']); |
|---|
| 71 | test('atree.matching.13', $god, 'examine me/FOO`*', |
|---|
| 72 | ['!FOO \[.*`\]', 'FOO`BAR \[', 'FOO`BAZ \[', '!FOO`BAR`BAZ \[[^`]+\]']); |
|---|
| 73 | # A single * doesn't match ` |
|---|
| 74 | test('atree.matching.14', $god, 'examine me/FOO*Z', |
|---|
| 75 | ['!FOO \[.*`\]', '!FOO`BAR \[', '!FOO`BAZ \[', '!FOO`BAR`BAZ \[[^`]+\]']); |
|---|
| 76 | # A double * does match ` |
|---|
| 77 | test('atree.matching.15', $god, 'examine me/FOO**Z', |
|---|
| 78 | ['!FOO \[.*`\]', '!FOO`BAR \[', 'FOO`BAZ \[', 'FOO`BAR`BAZ \[[^`]+\]']); |
|---|
| 79 | # @decompile gets everything by default |
|---|
| 80 | test('atree.matching.16', $god, '@decompile me', |
|---|
| 81 | ['&FOO ', '&FOO`BAR ', '&FOO`BAR`BAZ ']); |
|---|
| 82 | # But only the top layer if you say so |
|---|
| 83 | test('atree.matching.17', $god, '@decompile me/*', |
|---|
| 84 | ['&FOO ', '!&FOO`BAR ', '!&FOO`BAR`BAZ ']); |
|---|
| 85 | # lattr() works like examine, only top by default |
|---|
| 86 | test('atree.matching.18', $god, 'think lattr(me)', |
|---|
| 87 | ['\bFOO\b', '!\bFOO`BAR\b', '!\bFOO`BAR`BAZ\b']); |
|---|
| 88 | test('atree.matching.19', $god, 'think lattr(me/**)', |
|---|
| 89 | ['\bFOO\b', '\bFOO`BAR\b', '\bFOO`BAR`BAZ\b']); |
|---|
| 90 | test("atree.matching.20", $god, 'think flags(me/foo)', '`'); |
|---|
| 91 | |
|---|
| 92 | # Permissions checks |
|---|
| 93 | # Need a mortal for this... |
|---|
| 94 | test('atree.perms.1', $god, '@pcreate Mortal=mortal', 'created'); |
|---|
| 95 | $mortal = $mush->login("Mortal", "mortal"); |
|---|
| 96 | # Build a tree from different places... |
|---|
| 97 | test('atree.perms.2', $god, '&foo mortal=baz', 'Set'); |
|---|
| 98 | test('atree.perms.3', $god, '&foo`bar mortal=baz', 'Set'); |
|---|
| 99 | test('atree.perms.4', $mortal, '@decompile me', ['&FOO ', '&FOO`BAR ']); |
|---|
| 100 | test('atree.perms.5', $mortal, '&foo`bar me=baz', 'Set'); |
|---|
| 101 | test('atree.perms.6', $mortal, '&foo`bar`baz me=baz', 'Set'); |
|---|
| 102 | # Start flipping perms... |
|---|
| 103 | test('atree.perms.7', $god, '@set mortal/foo`bar=wiz', 'set'); |
|---|
| 104 | test('atree.perms.8', $mortal, '@decompile me', |
|---|
| 105 | ['&FOO ', '&FOO`BAR ', '&FOO`BAR`BAZ ']); |
|---|
| 106 | # Cannot overwrite wiz-only as mortal, or make stuff under it |
|---|
| 107 | test('atree.perms.9', $mortal, '&foo`bar me=baz', '!Set'); |
|---|
| 108 | test('atree.perms.10', $mortal, '&foo`bar`baz me=baz', '!Set'); |
|---|
| 109 | test('atree.perms.11', $mortal, '&foo`bar`qux me=baz', '!Set'); |
|---|
| 110 | # Cannot see under mortal_dark as mortal |
|---|
| 111 | test('atree.perms.12', $god, '@set mortal/foo`bar=mortal_dark', 'set'); |
|---|
| 112 | test('atree.perms.13', $mortal, '@decompile me', |
|---|
| 113 | ['&FOO ', '!&FOO`BAR ', '!&FOO`BAR`BAZ ', '!&FOO`BAR`QUX ']); |
|---|
| 114 | # Still can't write there (still wiz-only) |
|---|
| 115 | test('atree.perms.14', $mortal, '&foo`bar me=baz', '!Set'); |
|---|
| 116 | test('atree.perms.15', $mortal, '&foo`bar`baz me=baz', '!Set'); |
|---|
| 117 | test('atree.perms.16', $mortal, '&foo`bar`qux me=baz', '!Set'); |
|---|
| 118 | # Turn off wiz-only, but still can't see it... |
|---|
| 119 | test('atree.perms.17', $god, '@set mortal/foo`bar=!wiz', 'reset'); |
|---|
| 120 | test('atree.perms.18', $mortal, '@decompile me', |
|---|
| 121 | ['&FOO ', '!&FOO`BAR ', '!&FOO`BAR`BAZ ', '!&FOO`BAR`QUX ']); |
|---|
| 122 | # But you can write there again... |
|---|
| 123 | test('atree.perms.19', $mortal, '&foo`bar me=baz', 'Set'); |
|---|
| 124 | test('atree.perms.20', $mortal, '&foo`bar`baz me=baz', 'Set'); |
|---|
| 125 | test('atree.perms.21', $mortal, '&foo`bar`qux me=baz', 'Set'); |
|---|
| 126 | |
|---|
| 127 | # Parenting and ancestry |
|---|
| 128 | test('atree.parent.1', $mortal, '@create ancestor', 'Created'); |
|---|
| 129 | test('atree.parent.2', $mortal, '@create parent', 'Created'); |
|---|
| 130 | test('atree.parent.3', $mortal, '@create child', 'Created'); |
|---|
| 131 | test('atree.parent.4', $mortal, 'drop child', '.'); |
|---|
| 132 | test('atree.parent.5', $mortal, 'drop parent', '.'); |
|---|
| 133 | test('atree.parent.6', $mortal, 'drop ancestor', '.'); |
|---|
| 134 | test('atree.parent.7', $mortal, '@parent child=parent', 'Parent changed'); |
|---|
| 135 | test('atree.parent.8', $god, |
|---|
| 136 | '@config/set ancestor_thing=[after(num(ancestor),#)]', 'set'); |
|---|
| 137 | # Can we see stuff from the ancestor? |
|---|
| 138 | test('atree.parent.9', $mortal, '&foo ancestor=urk', 'Set'); |
|---|
| 139 | test('atree.parent.10', $mortal, '&foo`bar ancestor=urk', 'Set'); |
|---|
| 140 | test('atree.parent.11', $mortal, '&foo`bar`baz ancestor=urk', 'Set'); |
|---|
| 141 | test('atree.parent.12', $mortal, 'think get(child/foo)', 'urk'); |
|---|
| 142 | test('atree.parent.13', $mortal, 'think get(child/foo`bar)', 'urk'); |
|---|
| 143 | # Can we see stuff from the parent? |
|---|
| 144 | test('atree.parent.14', $mortal, '&foo parent=wibble', 'Set'); |
|---|
| 145 | test('atree.parent.15', $mortal, '&foo`bar parent=gleep', 'Set'); |
|---|
| 146 | test('atree.parent.16', $mortal, 'think get(child/foo)', 'wibble'); |
|---|
| 147 | test('atree.parent.17', $mortal, 'think get(child/foo`bar)', 'gleep'); |
|---|
| 148 | test('atree.parent.18', $mortal, '&foo`bar`baz child=boom', 'Set'); |
|---|
| 149 | test('atree.parent.19', $mortal, 'think -[get(child/foo)]-', '--'); |
|---|
| 150 | test('atree.parent.20', $mortal, 'think -[get(child/foo`bar)]-', '--'); |
|---|
| 151 | test('atree.parent.21', $mortal, '@wipe child/foo', 'wiped'); |
|---|
| 152 | # Setting no_inherit puts it back to the ancestor |
|---|
| 153 | test('atree.parent.22', $mortal, '@set parent/foo=no_inherit', 'set'); |
|---|
| 154 | test('atree.parent.23', $mortal, 'think get(child/foo)', '!wibble'); |
|---|
| 155 | test('atree.parent.24', $god, 'think get(child/foo`bar)', '!gleep'); |
|---|
| 156 | test('atree.parent.25', $god, 'think get(child/foo)', 'urk'); |
|---|
| 157 | test('atree.parent.26', $god, 'think get(child/foo`bar)', 'urk'); |
|---|
| 158 | |
|---|
| 159 | # Mix permissions and parents |
|---|
| 160 | # If parent is inheritable again, and mortal_dark, |
|---|
| 161 | # then we can't see the ancestor through it |
|---|
| 162 | test('atree.parentperms.1', $mortal, '@set parent/foo=!no_inherit', 'set'); |
|---|
| 163 | test('atree.parentperms.2', $god, '@set parent/foo`bar=mortal_dark', 'set'); |
|---|
| 164 | test('atree.parentperms.3', $mortal, 'think get(child/foo`bar`baz)', '!urk'); |
|---|
| 165 | # We can't see it, either |
|---|
| 166 | test('atree.parentperms.4', $mortal, 'think get(child/foo`bar)', '!gleep'); |
|---|
| 167 | test('atree.parentperms.5', $mortal, '@set parent/foo=no_inherit', 'set'); |
|---|
| 168 | # no_inherit trumps mortal_dark |
|---|
| 169 | test('atree.parentperms.6', $mortal, 'think get(child/foo`bar`baz)', 'urk'); |
|---|
| 170 | test('atree.parentperms.7', $mortal, 'think get(child/foo`bar)', 'urk'); |
|---|
| 171 | test('atree.parentperms.8', $god, '@set parent/foo=mortal_dark', 'set'); |
|---|
| 172 | test('atree.parentperms.9', $mortal, 'think get(child/foo`bar)', 'urk'); |
|---|
| 173 | |
|---|
| 174 | # Command checks |
|---|
| 175 | # Need explicit grandparent, because ancestors aren't checked for commands |
|---|
| 176 | test('atree.command.1', $mortal, '@create grand', []); |
|---|
| 177 | test('atree.command.2', $mortal, 'drop grand', []); |
|---|
| 178 | test('atree.command.3', $mortal, '@parent parent=grand', []); |
|---|
| 179 | test('atree.command.4', $mortal, '&bar grand=$bar:say Grand Bar', 'Set'); |
|---|
| 180 | test('atree.command.5', $mortal, '&bar`baz grand=$bar`baz:say Grand Baz', []); |
|---|
| 181 | test('atree.command.6', $mortal, '&bar parent=$bar:say Parent Bar', 'Set'); |
|---|
| 182 | test('atree.command.7', $mortal, '&bar`baz parent=$bar`baz:say Parent Baz', []); |
|---|
| 183 | test('atree.command.8', $mortal, '@set child=!no_command', 'set'); |
|---|
| 184 | # Do commands work from parent? |
|---|
| 185 | test('atree.command.9', $god, 'bar', '!Bar'); |
|---|
| 186 | test('atree.command.10', $god, undef, 'Parent Bar'); |
|---|
| 187 | test('atree.command.11', $god, 'bar`baz', []); |
|---|
| 188 | test('atree.command.12', $god, undef, 'Parent Baz'); |
|---|
| 189 | # Child should block parent |
|---|
| 190 | test('atree.command.13', $mortal, '&bar child=$bar:say Child!', 'Set'); |
|---|
| 191 | test('atree.command.14', $god, 'bar', '!Bar'); |
|---|
| 192 | test('atree.command.15', $god, undef, ['!Bar', 'Child']); |
|---|
| 193 | # Child no_command blocks parent branch, too |
|---|
| 194 | test('atree.command.16', $mortal, '@set child/bar=no_command', 'set'); |
|---|
| 195 | test('atree.command.17', $god, 'bar`baz', '!Baz'); |
|---|
| 196 | test('atree.command.18', $god, undef, '!Baz'); |
|---|
| 197 | # Parent no_command not masked by child not no_command... |
|---|
| 198 | test('atree.command.19', $mortal, '@set child/bar=!no_command', 'set'); |
|---|
| 199 | test('atree.command.20', $mortal, '@set parent/bar=no_command', 'set'); |
|---|
| 200 | test('atree.command.21', $god, 'bar`baz', '!Baz'); |
|---|
| 201 | test('atree.command.22', $god, undef, '!Baz'); |
|---|
| 202 | # no_command can be on the leaf, too |
|---|
| 203 | test('atree.command.23', $mortal, '@set parent/bar=!no_command', 'set'); |
|---|
| 204 | test('atree.command.24', $mortal, '@set parent/bar`baz=no_command', 'set'); |
|---|
| 205 | test('atree.command.25', $god, 'bar`baz', '!Baz'); |
|---|
| 206 | test('atree.command.26', $god, undef, '!Baz'); |
|---|
| 207 | # no_inherit trumps no_command |
|---|
| 208 | test('atree.command.27', $mortal, '@set parent/bar=no_inherit', 'set'); |
|---|
| 209 | test('atree.command.28', $mortal, '@set parent/bar`baz=no_command', 'set'); |
|---|
| 210 | test('atree.command.29', $god, 'bar`baz', '!Baz'); |
|---|
| 211 | test('atree.command.30', $god, undef, 'Grand Baz'); |
|---|
| 212 | test('atree.command.31', $mortal, '@set parent/bar=no_command', 'set'); |
|---|
| 213 | test('atree.command.32', $mortal, '&bar child', []); |
|---|
| 214 | test('atree.command.33', $god, 'bar', '!Baz'); |
|---|
| 215 | test('atree.command.34', $god, undef, 'Grand Bar'); |
|---|
| 216 | |
|---|
| 217 | # Test for the child recognition bugs: |
|---|
| 218 | test('atree.sortorder.1', $mortal, '&abc grand=$abc:say Grand ABC', 'Set'); |
|---|
| 219 | test('atree.sortorder.2', $mortal, '&abcd grand=$abcd:say Grand D', 'Set'); |
|---|
| 220 | test('atree.sortorder.3', $mortal, '&abc`xyz grand=$abc`xyz:say Grand XYZ', []); |
|---|
| 221 | test('atree.sortorder.4', $mortal, '&abc parent=$abc:say Parent ABC', 'Set'); |
|---|
| 222 | test('atree.sortorder.5', $mortal, '&abcd parent=$abcd:say Parent D', 'Set'); |
|---|
| 223 | test('atree.sortorder.6', $mortal, '&abc`xyz parent=$abc`xyz:say Parent XYZ', []); |
|---|
| 224 | test("atree.sortorder.7", $god, 'examine parent', 'ABC \[.*`\]'); |
|---|
| 225 | test("atree.sortorder.8", $god, '&abc parent', '!Cleared'); |
|---|
| 226 | test('atree.sortorder.9', $mortal, '@set child=!no_command', 'set'); |
|---|
| 227 | # Do commands work from parent? |
|---|
| 228 | test('atree.sortorder.10', $god, 'abc', '!ABC'); |
|---|
| 229 | test('atree.sortorder.11', $god, undef, 'Parent ABC'); |
|---|
| 230 | test('atree.sortorder.12', $god, 'abc`xyz', []); |
|---|
| 231 | test('atree.sortorder.13', $god, undef, 'Parent XYZ'); |
|---|
| 232 | # Child should block parent |
|---|
| 233 | test('atree.sortorder.14', $mortal, '&abc child=$abc:say Child!', 'Set'); |
|---|
| 234 | test('atree.sortorder.15', $god, 'abc', '!ABC'); |
|---|
| 235 | test('atree.sortorder.16', $god, undef, ['!ABC', 'Child']); |
|---|
| 236 | # Child no_command blocks parent branch, too |
|---|
| 237 | test('atree.sortorder.17', $mortal, '@set child/abc=no_command', 'set'); |
|---|
| 238 | test('atree.sortorder.18', $god, 'abc`xyz', '!XYZ'); |
|---|
| 239 | test('atree.sortorder.19', $god, undef, '!XYZ'); |
|---|
| 240 | # Parent no_command not masked by child not no_command... |
|---|
| 241 | test('atree.sortorder.20', $mortal, '@set child/abc=!no_command', 'set'); |
|---|
| 242 | test('atree.sortorder.21', $mortal, '@set parent/abc=no_command', 'set'); |
|---|
| 243 | test('atree.sortorder.22', $god, 'abc`xyz', '!XYZ'); |
|---|
| 244 | test('atree.sortorder.23', $god, undef, '!XYZ'); |
|---|
| 245 | # no_command can be on the leaf, too |
|---|
| 246 | test('atree.sortorder.24', $mortal, '@set parent/abc=!no_command', 'set'); |
|---|
| 247 | test('atree.sortorder.25', $mortal, '@set parent/abc`xyz=no_command', 'set'); |
|---|
| 248 | test('atree.sortorder.26', $god, 'abc`xyz', '!XYZ'); |
|---|
| 249 | test('atree.sortorder.27', $god, undef, '!XYZ'); |
|---|
| 250 | # no_inherit trumps no_command |
|---|
| 251 | test('atree.sortorder.28', $mortal, '@set parent/abc=no_inherit', 'set'); |
|---|
| 252 | test('atree.sortorder.29', $mortal, '@set parent/abc`xyz=no_command', 'set'); |
|---|
| 253 | test('atree.sortorder.30', $god, 'abc`xyz', '!XYZ'); |
|---|
| 254 | test('atree.sortorder.31', $god, undef, 'Grand XYZ'); |
|---|
| 255 | test('atree.sortorder.32', $mortal, '@set parent/abc=no_command', 'set'); |
|---|
| 256 | test('atree.sortorder.33', $mortal, '&abc child', []); |
|---|
| 257 | test('atree.sortorder.34', $god, 'abc', '!XYZ'); |
|---|
| 258 | test('atree.sortorder.35', $god, undef, 'Grand ABC'); |
|---|
| 259 | # wipe check |
|---|
| 260 | test("atree.sortorder.36", $god, '@wipe parent', 'wiped'); |
|---|
| 261 | test("atree.sortorder.37", $god, '@wipe grand/abc', []); |
|---|
| 262 | test("atree.sortorder.38", $god, 'examine grand/**', '!ABC\b'); |
|---|