1;;;; environments.test -*- scheme -*- 2;;;; Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc. 3;;;; 4;;;; This library is free software; you can redistribute it and/or 5;;;; modify it under the terms of the GNU Lesser General Public 6;;;; License as published by the Free Software Foundation; either 7;;;; version 2.1 of the License, or (at your option) any later version. 8;;;; 9;;;; This library is distributed in the hope that it will be useful, 10;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of 11;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12;;;; Lesser General Public License for more details. 13;;;; 14;;;; You should have received a copy of the GNU Lesser General Public 15;;;; License along with this library; if not, write to the Free Software 16;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 18(use-modules (ice-9 documentation)) 19 20 21;;; 22;;; miscellaneous 23;;; 24 25(define exception:unbound-symbol 26 (cons 'misc-error "^Symbol .* not bound in environment")) 27 28(define (documented? object) 29 (not (not (object-documentation object)))) 30 31(define (folder sym val res) 32 (cons (cons sym val) res)) 33 34(define (make-observer-func) 35 (let* ((counter 0)) 36 (lambda args 37 (if (null? args) 38 counter 39 (set! counter (+ counter 1)))))) 40 41(define (make-erroneous-observer-func) 42 (let* ((func (make-observer-func))) 43 (lambda args 44 (if (null? args) 45 (func) 46 (begin 47 (func args) 48 (error)))))) 49 50;;; 51;;; leaf-environments 52;;; 53 54(with-test-prefix "leaf-environments" 55 56 (with-test-prefix "leaf-environment?" 57 58 (pass-if "documented?" 59 (documented? leaf-environment?)) 60 61 (pass-if "non-environment-object" 62 (not (leaf-environment? #f)))) 63 64 65 (with-test-prefix "make-leaf-environment" 66 67 (pass-if "documented?" 68 (documented? make-leaf-environment)) 69 70 (pass-if "produces an environment" 71 (environment? (make-leaf-environment))) 72 73 (pass-if "produces a leaf-environment" 74 (leaf-environment? (make-leaf-environment))) 75 76 (pass-if "produces always a new environment" 77 (not (eq? (make-leaf-environment) (make-leaf-environment))))) 78 79 80 (with-test-prefix "bound, define, ref, set!, cell" 81 82 (pass-if "symbols are unbound by default" 83 (let* ((env (make-leaf-environment))) 84 (and (not (environment-bound? env 'a)) 85 (not (environment-bound? env 'b)) 86 (not (environment-bound? env 'c))))) 87 88 (pass-if "symbol is bound after define" 89 (let* ((env (make-leaf-environment))) 90 (environment-bound? env 'a) 91 (environment-define env 'a #t) 92 (environment-bound? env 'a))) 93 94 (pass-if "ref a defined symbol" 95 (let* ((env (make-leaf-environment))) 96 (environment-bound? env 'a) 97 (environment-bound? env 'b) 98 (environment-define env 'a #t) 99 (environment-define env 'b #f) 100 (and (environment-ref env 'a) 101 (not (environment-ref env 'b))))) 102 103 (pass-if "set! a defined symbol" 104 (let* ((env (make-leaf-environment))) 105 (environment-define env 'a #t) 106 (environment-define env 'b #f) 107 (environment-ref env 'a) 108 (environment-ref env 'b) 109 (environment-set! env 'a #f) 110 (environment-set! env 'b #t) 111 (and (not (environment-ref env 'a)) 112 (environment-ref env 'b)))) 113 114 (pass-if "get a read-only cell" 115 (let* ((env (make-leaf-environment))) 116 (environment-define env 'a #t) 117 (let* ((cell (environment-cell env 'a #f))) 118 (and (cdr cell) 119 (begin 120 (environment-set! env 'a #f) 121 (not (cdr cell))))))) 122 123 (pass-if "a read-only cell gets rebound after define" 124 (let* ((env (make-leaf-environment))) 125 (environment-define env 'a #t) 126 (let* ((cell (environment-cell env 'a #f))) 127 (environment-define env 'a #f) 128 (not (eq? (environment-cell env 'a #f) cell))))) 129 130 (pass-if "get a writable cell" 131 (let* ((env (make-leaf-environment))) 132 (environment-define env 'a #t) 133 (let* ((readable (environment-cell env 'a #f)) 134 (writable (environment-cell env 'a #t))) 135 (and (eq? readable writable) 136 (begin 137 (environment-set! env 'a #f) 138 (not (cdr writable))) 139 (begin 140 (set-cdr! writable #t) 141 (environment-ref env 'a)) 142 (begin 143 (set-cdr! (environment-cell env 'a #t) #f) 144 (not (cdr writable))))))) 145 146 (pass-if "a writable cell gets rebound after define" 147 (let* ((env (make-leaf-environment))) 148 (environment-define env 'a #t) 149 (let* ((cell (environment-cell env 'a #t))) 150 (environment-define env 'a #f) 151 (not (eq? (environment-cell env 'a #t) cell))))) 152 153 (pass-if-exception "reference an unbound symbol" 154 exception:unbound-symbol 155 (environment-ref (make-leaf-environment) 'a)) 156 157 (pass-if-exception "set! an unbound symbol" 158 exception:unbound-symbol 159 (environment-set! (make-leaf-environment) 'a #f)) 160 161 (pass-if-exception "get a readable cell for an unbound symbol" 162 exception:unbound-symbol 163 (environment-cell (make-leaf-environment) 'a #f)) 164 165 (pass-if-exception "get a writable cell for an unbound symbol" 166 exception:unbound-symbol 167 (environment-cell (make-leaf-environment) 'a #t))) 168 169 170 (with-test-prefix "undefine" 171 172 (pass-if "undefine a defined symbol" 173 (let* ((env (make-leaf-environment))) 174 (environment-define env 'a 1) 175 (environment-ref env 'a) 176 (environment-undefine env 'a) 177 (not (environment-bound? env 'a)))) 178 179 (pass-if "undefine an already undefined symbol" 180 (environment-undefine (make-leaf-environment) 'a) 181 #t)) 182 183 184 (with-test-prefix "fold" 185 186 (pass-if "empty environment" 187 (let* ((env (make-leaf-environment))) 188 (eq? 'success (environment-fold env folder 'success)))) 189 190 (pass-if "one symbol" 191 (let* ((env (make-leaf-environment))) 192 (environment-define env 'a #t) 193 (equal? '((a . #t)) (environment-fold env folder '())))) 194 195 (pass-if "two symbols" 196 (let* ((env (make-leaf-environment))) 197 (environment-define env 'a #t) 198 (environment-define env 'b #f) 199 (let ((folded (environment-fold env folder '()))) 200 (or (equal? folded '((a . #t) (b . #f))) 201 (equal? folded '((b . #f) (a . #t)))))))) 202 203 204 (with-test-prefix "observe" 205 206 (pass-if "observe an environment" 207 (let* ((env (make-leaf-environment))) 208 (environment-observe env (make-observer-func)) 209 #t)) 210 211 (pass-if "observe an environment twice" 212 (let* ((env (make-leaf-environment)) 213 (observer-1 (environment-observe env (make-observer-func))) 214 (observer-2 (environment-observe env (make-observer-func)))) 215 (not (eq? observer-1 observer-2)))) 216 217 (pass-if "definition of an undefined symbol" 218 (let* ((env (make-leaf-environment)) 219 (func (make-observer-func))) 220 (environment-observe env func) 221 (environment-define env 'a 1) 222 (eqv? (func) 1))) 223 224 (pass-if "definition of an already defined symbol" 225 (let* ((env (make-leaf-environment))) 226 (environment-define env 'a 1) 227 (let* ((func (make-observer-func))) 228 (environment-observe env func) 229 (environment-define env 'a 1) 230 (eqv? (func) 1)))) 231 232 (pass-if "set!ing of a defined symbol" 233 (let* ((env (make-leaf-environment))) 234 (environment-define env 'a 1) 235 (let* ((func (make-observer-func))) 236 (environment-observe env func) 237 (environment-set! env 'a 1) 238 (eqv? (func) 0)))) 239 240 (pass-if "undefining a defined symbol" 241 (let* ((env (make-leaf-environment))) 242 (environment-define env 'a 1) 243 (let* ((func (make-observer-func))) 244 (environment-observe env func) 245 (environment-undefine env 'a) 246 (eqv? (func) 1)))) 247 248 (pass-if "undefining an already undefined symbol" 249 (let* ((env (make-leaf-environment)) 250 (func (make-observer-func))) 251 (environment-observe env func) 252 (environment-undefine env 'a) 253 (eqv? (func) 0))) 254 255 (pass-if "unobserve an active observer" 256 (let* ((env (make-leaf-environment)) 257 (func (make-observer-func)) 258 (observer (environment-observe env func))) 259 (environment-unobserve observer) 260 (environment-define env 'a 1) 261 (eqv? (func) 0))) 262 263 (pass-if "unobserve an inactive observer" 264 (let* ((env (make-leaf-environment)) 265 (func (make-observer-func)) 266 (observer (environment-observe env func))) 267 (environment-unobserve observer) 268 (environment-unobserve observer) 269 #t))) 270 271 272 (with-test-prefix "observe-weak" 273 274 (pass-if "observe an environment" 275 (let* ((env (make-leaf-environment))) 276 (environment-observe-weak env (make-observer-func)) 277 #t)) 278 279 (pass-if "observe an environment twice" 280 (let* ((env (make-leaf-environment)) 281 (observer-1 (environment-observe-weak env (make-observer-func))) 282 (observer-2 (environment-observe-weak env (make-observer-func)))) 283 (not (eq? observer-1 observer-2)))) 284 285 (pass-if "definition of an undefined symbol" 286 (let* ((env (make-leaf-environment)) 287 (func (make-observer-func))) 288 (environment-observe-weak env func) 289 (environment-define env 'a 1) 290 (eqv? (func) 1))) 291 292 (pass-if "definition of an already defined symbol" 293 (let* ((env (make-leaf-environment))) 294 (environment-define env 'a 1) 295 (let* ((func (make-observer-func))) 296 (environment-observe-weak env func) 297 (environment-define env 'a 1) 298 (eqv? (func) 1)))) 299 300 (pass-if "set!ing of a defined symbol" 301 (let* ((env (make-leaf-environment))) 302 (environment-define env 'a 1) 303 (let* ((func (make-observer-func))) 304 (environment-observe-weak env func) 305 (environment-set! env 'a 1) 306 (eqv? (func) 0)))) 307 308 (pass-if "undefining a defined symbol" 309 (let* ((env (make-leaf-environment))) 310 (environment-define env 'a 1) 311 (let* ((func (make-observer-func))) 312 (environment-observe-weak env func) 313 (environment-undefine env 'a) 314 (eqv? (func) 1)))) 315 316 (pass-if "undefining an already undefined symbol" 317 (let* ((env (make-leaf-environment)) 318 (func (make-observer-func))) 319 (environment-observe-weak env func) 320 (environment-undefine env 'a) 321 (eqv? (func) 0))) 322 323 (pass-if "unobserve an active observer" 324 (let* ((env (make-leaf-environment)) 325 (func (make-observer-func)) 326 (observer (environment-observe-weak env func))) 327 (environment-unobserve observer) 328 (environment-define env 'a 1) 329 (eqv? (func) 0))) 330 331 (pass-if "unobserve an inactive observer" 332 (let* ((env (make-leaf-environment)) 333 (func (make-observer-func)) 334 (observer (environment-observe-weak env func))) 335 (environment-unobserve observer) 336 (environment-unobserve observer) 337 #t)) 338 339 (pass-if "weak observer gets collected" 340 (gc) 341 (let* ((env (make-leaf-environment)) 342 (func (make-observer-func))) 343 (environment-observe-weak env func) 344 (gc) 345 (environment-define env 'a 1) 346 (if (not (eqv? (func) 0)) 347 (throw 'unresolved) ; note: conservative scanning 348 #t)))) 349 350 351 (with-test-prefix "erroneous observers" 352 353 (pass-if "update continues after error" 354 (let* ((env (make-leaf-environment)) 355 (func-1 (make-erroneous-observer-func)) 356 (func-2 (make-erroneous-observer-func))) 357 (environment-observe env func-1) 358 (environment-observe env func-2) 359 (catch #t 360 (lambda () 361 (environment-define env 'a 1) 362 #f) 363 (lambda args 364 (and (eq? (func-1) 1) 365 (eq? (func-2) 1)))))))) 366 367 368;;; 369;;; leaf-environment based eval-environments 370;;; 371 372(with-test-prefix "leaf-environment based eval-environments" 373 374 (with-test-prefix "eval-environment?" 375 376 (pass-if "documented?" 377 (documented? eval-environment?)) 378 379 (pass-if "non-environment-object" 380 (not (eval-environment? #f))) 381 382 (pass-if "leaf-environment-object" 383 (not (eval-environment? (make-leaf-environment))))) 384 385 386 (with-test-prefix "make-eval-environment" 387 388 (pass-if "documented?" 389 (documented? make-eval-environment)) 390 391 (let* ((local (make-leaf-environment)) 392 (imported (make-leaf-environment))) 393 394 (pass-if "produces an environment" 395 (environment? (make-eval-environment local imported))) 396 397 (pass-if "produces an eval-environment" 398 (eval-environment? (make-eval-environment local imported))) 399 400 (pass-if "produces always a new environment" 401 (not (eq? (make-eval-environment local imported) 402 (make-eval-environment local imported)))))) 403 404 405 (with-test-prefix "eval-environment-local" 406 407 (pass-if "documented?" 408 (documented? eval-environment-local)) 409 410 (pass-if "returns local" 411 (let* ((local (make-leaf-environment)) 412 (imported (make-leaf-environment)) 413 (env (make-eval-environment local imported))) 414 (eq? (eval-environment-local env) local)))) 415 416 417 (with-test-prefix "eval-environment-imported" 418 419 (pass-if "documented?" 420 (documented? eval-environment-imported)) 421 422 (pass-if "returns imported" 423 (let* ((local (make-leaf-environment)) 424 (imported (make-leaf-environment)) 425 (env (make-eval-environment local imported))) 426 (eq? (eval-environment-imported env) imported)))) 427 428 429 (with-test-prefix "bound, define, ref, set!, cell" 430 431 (pass-if "symbols are unbound by default" 432 (let* ((local (make-leaf-environment)) 433 (imported (make-leaf-environment)) 434 (env (make-eval-environment local imported))) 435 (and (not (environment-bound? env 'a)) 436 (not (environment-bound? env 'b)) 437 (not (environment-bound? env 'c))))) 438 439 (with-test-prefix "symbols bound in imported" 440 441 (pass-if "binding is visible" 442 (let* ((local (make-leaf-environment)) 443 (imported (make-leaf-environment)) 444 (env (make-eval-environment local imported))) 445 (environment-bound? env 'a) 446 (environment-define imported 'a #t) 447 (environment-bound? env 'a))) 448 449 (pass-if "ref works" 450 (let* ((local (make-leaf-environment)) 451 (imported (make-leaf-environment)) 452 (env (make-eval-environment local imported))) 453 (environment-bound? env 'a) 454 (environment-define imported 'a #t) 455 (environment-ref env 'a))) 456 457 (pass-if "set! works" 458 (let* ((local (make-leaf-environment)) 459 (imported (make-leaf-environment)) 460 (env (make-eval-environment local imported))) 461 (environment-define imported 'a #f) 462 (environment-set! env 'a #t) 463 (environment-ref imported 'a))) 464 465 (pass-if "cells are passed through" 466 (let* ((local (make-leaf-environment)) 467 (imported (make-leaf-environment)) 468 (env (make-eval-environment local imported))) 469 (environment-define imported 'a #t) 470 (let* ((imported-cell (environment-cell imported 'a #f)) 471 (env-cell (environment-cell env 'a #f))) 472 (eq? env-cell imported-cell))))) 473 474 (with-test-prefix "symbols bound in local" 475 476 (pass-if "binding is visible" 477 (let* ((local (make-leaf-environment)) 478 (imported (make-leaf-environment)) 479 (env (make-eval-environment local imported))) 480 (environment-bound? env 'a) 481 (environment-define local 'a #t) 482 (environment-bound? env 'a))) 483 484 (pass-if "ref works" 485 (let* ((local (make-leaf-environment)) 486 (imported (make-leaf-environment)) 487 (env (make-eval-environment local imported))) 488 (environment-define local 'a #t) 489 (environment-ref env 'a))) 490 491 (pass-if "set! works" 492 (let* ((local (make-leaf-environment)) 493 (imported (make-leaf-environment)) 494 (env (make-eval-environment local imported))) 495 (environment-define local 'a #f) 496 (environment-set! env 'a #t) 497 (environment-ref local 'a))) 498 499 (pass-if "cells are passed through" 500 (let* ((local (make-leaf-environment)) 501 (imported (make-leaf-environment)) 502 (env (make-eval-environment local imported))) 503 (environment-define local 'a #t) 504 (let* ((local-cell (environment-cell local 'a #f)) 505 (env-cell (environment-cell env 'a #f))) 506 (eq? env-cell local-cell))))) 507 508 (with-test-prefix "symbols bound in local and imported" 509 510 (pass-if "binding is visible" 511 (let* ((local (make-leaf-environment)) 512 (imported (make-leaf-environment)) 513 (env (make-eval-environment local imported))) 514 (environment-bound? env 'a) 515 (environment-define imported 'a #t) 516 (environment-define local 'a #f) 517 (environment-bound? env 'a))) 518 519 (pass-if "ref works" 520 (let* ((local (make-leaf-environment)) 521 (imported (make-leaf-environment)) 522 (env (make-eval-environment local imported))) 523 (environment-define imported 'a #f) 524 (environment-define local 'a #t) 525 (environment-ref env 'a))) 526 527 (pass-if "set! changes local" 528 (let* ((local (make-leaf-environment)) 529 (imported (make-leaf-environment)) 530 (env (make-eval-environment local imported))) 531 (environment-define imported 'a #f) 532 (environment-define local 'a #f) 533 (environment-set! env 'a #t) 534 (environment-ref local 'a))) 535 536 (pass-if "set! does not touch imported" 537 (let* ((local (make-leaf-environment)) 538 (imported (make-leaf-environment)) 539 (env (make-eval-environment local imported))) 540 (environment-define imported 'a #t) 541 (environment-define local 'a #t) 542 (environment-set! env 'a #f) 543 (environment-ref imported 'a))) 544 545 (pass-if "cells from local are passed through" 546 (let* ((local (make-leaf-environment)) 547 (imported (make-leaf-environment)) 548 (env (make-eval-environment local imported))) 549 (environment-define local 'a #t) 550 (let* ((local-cell (environment-cell local 'a #f)) 551 (env-cell (environment-cell env 'a #f))) 552 (eq? env-cell local-cell))))) 553 554 (with-test-prefix "defining symbols" 555 556 (pass-if "symbols are bound in local after define" 557 (let* ((local (make-leaf-environment)) 558 (imported (make-leaf-environment)) 559 (env (make-eval-environment local imported))) 560 (environment-define env 'a #t) 561 (environment-bound? local 'a))) 562 563 (pass-if "cells in local get rebound after define" 564 (let* ((local (make-leaf-environment)) 565 (imported (make-leaf-environment)) 566 (env (make-eval-environment local imported))) 567 (environment-define env 'a #f) 568 (let* ((old-cell (environment-cell local 'a #f))) 569 (environment-define env 'a #f) 570 (let* ((new-cell (environment-cell local 'a #f))) 571 (not (eq? new-cell old-cell)))))) 572 573 (pass-if "cells in imported get shadowed after define" 574 (let* ((local (make-leaf-environment)) 575 (imported (make-leaf-environment)) 576 (env (make-eval-environment local imported))) 577 (environment-define imported 'a #f) 578 (environment-define env 'a #t) 579 (environment-ref local 'a)))) 580 581 (let* ((local (make-leaf-environment)) 582 (imported (make-leaf-environment)) 583 (env (make-eval-environment local imported))) 584 585 (pass-if-exception "reference an unbound symbol" 586 exception:unbound-symbol 587 (environment-ref env 'b)) 588 589 (pass-if-exception "set! an unbound symbol" 590 exception:unbound-symbol 591 (environment-set! env 'b #f)) 592 593 (pass-if-exception "get a readable cell for an unbound symbol" 594 exception:unbound-symbol 595 (environment-cell env 'b #f)) 596 597 (pass-if-exception "get a writable cell for an unbound symbol" 598 exception:unbound-symbol 599 (environment-cell env 'b #t)))) 600 601 (with-test-prefix "eval-environment-set-local!" 602 603 (pass-if "documented?" 604 (documented? eval-environment-set-local!)) 605 606 (pass-if "new binding becomes visible" 607 (let* ((old-local (make-leaf-environment)) 608 (new-local (make-leaf-environment)) 609 (imported (make-leaf-environment)) 610 (env (make-eval-environment old-local imported))) 611 (environment-bound? env 'a) 612 (environment-define new-local 'a #t) 613 (eval-environment-set-local! env new-local) 614 (environment-bound? env 'a))) 615 616 (pass-if "existing binding is replaced" 617 (let* ((old-local (make-leaf-environment)) 618 (new-local (make-leaf-environment)) 619 (imported (make-leaf-environment)) 620 (env (make-eval-environment old-local imported))) 621 (environment-define old-local 'a #f) 622 (environment-ref env 'a) 623 (environment-define new-local 'a #t) 624 (eval-environment-set-local! env new-local) 625 (environment-ref env 'a))) 626 627 (pass-if "undefined binding is removed" 628 (let* ((old-local (make-leaf-environment)) 629 (new-local (make-leaf-environment)) 630 (imported (make-leaf-environment)) 631 (env (make-eval-environment old-local imported))) 632 (environment-define old-local 'a #f) 633 (environment-ref env 'a) 634 (eval-environment-set-local! env new-local) 635 (not (environment-bound? env 'a)))) 636 637 (pass-if "binding in imported remains shadowed" 638 (let* ((old-local (make-leaf-environment)) 639 (new-local (make-leaf-environment)) 640 (imported (make-leaf-environment)) 641 (env (make-eval-environment old-local imported))) 642 (environment-define imported 'a #f) 643 (environment-define old-local 'a #f) 644 (environment-ref env 'a) 645 (environment-define new-local 'a #t) 646 (eval-environment-set-local! env new-local) 647 (environment-ref env 'a))) 648 649 (pass-if "binding in imported gets shadowed" 650 (let* ((old-local (make-leaf-environment)) 651 (new-local (make-leaf-environment)) 652 (imported (make-leaf-environment)) 653 (env (make-eval-environment old-local imported))) 654 (environment-define imported 'a #f) 655 (environment-ref env 'a) 656 (environment-define new-local 'a #t) 657 (eval-environment-set-local! env new-local) 658 (environment-ref env 'a))) 659 660 (pass-if "binding in imported becomes visible" 661 (let* ((old-local (make-leaf-environment)) 662 (new-local (make-leaf-environment)) 663 (imported (make-leaf-environment)) 664 (env (make-eval-environment old-local imported))) 665 (environment-define imported 'a #t) 666 (environment-define old-local 'a #f) 667 (environment-ref env 'a) 668 (eval-environment-set-local! env new-local) 669 (environment-ref env 'a)))) 670 671 (with-test-prefix "eval-environment-set-imported!" 672 673 (pass-if "documented?" 674 (documented? eval-environment-set-imported!)) 675 676 (pass-if "new binding becomes visible" 677 (let* ((local (make-leaf-environment)) 678 (old-imported (make-leaf-environment)) 679 (new-imported (make-leaf-environment)) 680 (env (make-eval-environment local old-imported))) 681 (environment-bound? env 'a) 682 (environment-define new-imported 'a #t) 683 (eval-environment-set-imported! env new-imported) 684 (environment-bound? env 'a))) 685 686 (pass-if "existing binding is replaced" 687 (let* ((local (make-leaf-environment)) 688 (old-imported (make-leaf-environment)) 689 (new-imported (make-leaf-environment)) 690 (env (make-eval-environment local old-imported))) 691 (environment-define old-imported 'a #f) 692 (environment-ref env 'a) 693 (environment-define new-imported 'a #t) 694 (eval-environment-set-imported! env new-imported) 695 (environment-ref env 'a))) 696 697 (pass-if "undefined binding is removed" 698 (let* ((local (make-leaf-environment)) 699 (old-imported (make-leaf-environment)) 700 (new-imported (make-leaf-environment)) 701 (env (make-eval-environment local old-imported))) 702 (environment-define old-imported 'a #f) 703 (environment-ref env 'a) 704 (eval-environment-set-imported! env new-imported) 705 (not (environment-bound? env 'a)))) 706 707 (pass-if "binding in imported remains shadowed" 708 (let* ((local (make-leaf-environment)) 709 (old-imported (make-leaf-environment)) 710 (new-imported (make-leaf-environment)) 711 (env (make-eval-environment local old-imported))) 712 (environment-define local 'a #t) 713 (environment-define old-imported 'a #f) 714 (environment-ref env 'a) 715 (environment-define new-imported 'a #t) 716 (eval-environment-set-imported! env new-imported) 717 (environment-ref env 'a))) 718 719 (pass-if "binding in imported gets shadowed" 720 (let* ((local (make-leaf-environment)) 721 (old-imported (make-leaf-environment)) 722 (new-imported (make-leaf-environment)) 723 (env (make-eval-environment local old-imported))) 724 (environment-define local 'a #t) 725 (environment-ref env 'a) 726 (environment-define new-imported 'a #f) 727 (eval-environment-set-imported! env new-imported) 728 (environment-ref env 'a)))) 729 730 (with-test-prefix "undefine" 731 732 (pass-if "undefine an already undefined symbol" 733 (let* ((local (make-leaf-environment)) 734 (imported (make-leaf-environment)) 735 (env (make-eval-environment local imported))) 736 (environment-undefine env 'a) 737 #t)) 738 739 (pass-if "undefine removes a binding from local" 740 (let* ((local (make-leaf-environment)) 741 (imported (make-leaf-environment)) 742 (env (make-eval-environment local imported))) 743 (environment-define local 'a #t) 744 (environment-undefine env 'a) 745 (not (environment-bound? local 'a)))) 746 747 (pass-if "undefine does not influence imported" 748 (let* ((local (make-leaf-environment)) 749 (imported (make-leaf-environment)) 750 (env (make-eval-environment local imported))) 751 (environment-define imported 'a #t) 752 (environment-undefine env 'a) 753 (environment-bound? imported 'a))) 754 755 (pass-if "undefine an imported symbol does not undefine it" 756 (let* ((local (make-leaf-environment)) 757 (imported (make-leaf-environment)) 758 (env (make-eval-environment local imported))) 759 (environment-define imported 'a #t) 760 (environment-undefine env 'a) 761 (environment-bound? env 'a))) 762 763 (pass-if "undefine unshadows an imported symbol" 764 (let* ((local (make-leaf-environment)) 765 (imported (make-leaf-environment)) 766 (env (make-eval-environment local imported))) 767 (environment-define imported 'a #t) 768 (environment-define local 'a #f) 769 (environment-undefine env 'a) 770 (environment-ref env 'a)))) 771 772 (with-test-prefix "fold" 773 774 (pass-if "empty environment" 775 (let* ((local (make-leaf-environment)) 776 (imported (make-leaf-environment)) 777 (env (make-eval-environment local imported))) 778 (eq? 'success (environment-fold env folder 'success)))) 779 780 (pass-if "one symbol in local" 781 (let* ((local (make-leaf-environment)) 782 (imported (make-leaf-environment)) 783 (env (make-eval-environment local imported))) 784 (environment-define local 'a #t) 785 (equal? '((a . #t)) (environment-fold env folder '())))) 786 787 (pass-if "one symbol in imported" 788 (let* ((local (make-leaf-environment)) 789 (imported (make-leaf-environment)) 790 (env (make-eval-environment local imported))) 791 (environment-define imported 'a #t) 792 (equal? '((a . #t)) (environment-fold env folder '())))) 793 794 (pass-if "shadowed symbol" 795 (let* ((local (make-leaf-environment)) 796 (imported (make-leaf-environment)) 797 (env (make-eval-environment local imported))) 798 (environment-define local 'a #t) 799 (environment-define imported 'a #f) 800 (equal? '((a . #t)) (environment-fold env folder '())))) 801 802 (pass-if "one symbol each" 803 (let* ((local (make-leaf-environment)) 804 (imported (make-leaf-environment)) 805 (env (make-eval-environment local imported))) 806 (environment-define local 'a #t) 807 (environment-define imported 'b #f) 808 (let ((folded (environment-fold env folder '()))) 809 (or (equal? folded '((a . #t) (b . #f))) 810 (equal? folded '((b . #f) (a . #t)))))))) 811 812 813 (with-test-prefix "observe" 814 815 (pass-if "observe an environment" 816 (let* ((local (make-leaf-environment)) 817 (imported (make-leaf-environment)) 818 (env (make-eval-environment local imported))) 819 (environment-observe env (make-observer-func)) 820 #t)) 821 822 (pass-if "observe an environment twice" 823 (let* ((local (make-leaf-environment)) 824 (imported (make-leaf-environment)) 825 (env (make-eval-environment local imported)) 826 (observer-1 (environment-observe env (make-observer-func))) 827 (observer-2 (environment-observe env (make-observer-func)))) 828 (not (eq? observer-1 observer-2)))) 829 830 (pass-if "definition of an undefined symbol" 831 (let* ((local (make-leaf-environment)) 832 (imported (make-leaf-environment)) 833 (env (make-eval-environment local imported)) 834 (func (make-observer-func))) 835 (environment-observe env func) 836 (environment-define env 'a 1) 837 (eqv? (func) 1))) 838 839 (pass-if "definition of an already defined symbol" 840 (let* ((local (make-leaf-environment)) 841 (imported (make-leaf-environment)) 842 (env (make-eval-environment local imported))) 843 (environment-define env 'a 1) 844 (let* ((func (make-observer-func))) 845 (environment-observe env func) 846 (environment-define env 'a 1) 847 (eqv? (func) 1)))) 848 849 (pass-if "set!ing of a defined symbol" 850 (let* ((local (make-leaf-environment)) 851 (imported (make-leaf-environment)) 852 (env (make-eval-environment local imported))) 853 (environment-define env 'a 1) 854 (let* ((func (make-observer-func))) 855 (environment-observe env func) 856 (environment-set! env 'a 1) 857 (eqv? (func) 0)))) 858 859 (pass-if "undefining a defined symbol" 860 (let* ((local (make-leaf-environment)) 861 (imported (make-leaf-environment)) 862 (env (make-eval-environment local imported))) 863 (environment-define env 'a 1) 864 (let* ((func (make-observer-func))) 865 (environment-observe env func) 866 (environment-undefine env 'a) 867 (eqv? (func) 1)))) 868 869 (pass-if "undefining an already undefined symbol" 870 (let* ((local (make-leaf-environment)) 871 (imported (make-leaf-environment)) 872 (env (make-eval-environment local imported)) 873 (func (make-observer-func))) 874 (environment-observe env func) 875 (environment-undefine env 'a) 876 (eqv? (func) 0))) 877 878 (pass-if "unobserve an active observer" 879 (let* ((local (make-leaf-environment)) 880 (imported (make-leaf-environment)) 881 (env (make-eval-environment local imported)) 882 (func (make-observer-func)) 883 (observer (environment-observe env func))) 884 (environment-unobserve observer) 885 (environment-define env 'a 1) 886 (eqv? (func) 0))) 887 888 (pass-if "unobserve an inactive observer" 889 (let* ((local (make-leaf-environment)) 890 (imported (make-leaf-environment)) 891 (env (make-eval-environment local imported)) 892 (func (make-observer-func)) 893 (observer (environment-observe env func))) 894 (environment-unobserve observer) 895 (environment-unobserve observer) 896 #t))) 897 898 899 (with-test-prefix "observe-weak" 900 901 (pass-if "observe an environment" 902 (let* ((local (make-leaf-environment)) 903 (imported (make-leaf-environment)) 904 (env (make-eval-environment local imported))) 905 (environment-observe-weak env (make-observer-func)) 906 #t)) 907 908 (pass-if "observe an environment twice" 909 (let* ((local (make-leaf-environment)) 910 (imported (make-leaf-environment)) 911 (env (make-eval-environment local imported)) 912 (observer-1 (environment-observe-weak env (make-observer-func))) 913 (observer-2 (environment-observe-weak env (make-observer-func)))) 914 (not (eq? observer-1 observer-2)))) 915 916 (pass-if "definition of an undefined symbol" 917 (let* ((local (make-leaf-environment)) 918 (imported (make-leaf-environment)) 919 (env (make-eval-environment local imported)) 920 (func (make-observer-func))) 921 (environment-observe-weak env func) 922 (environment-define env 'a 1) 923 (eqv? (func) 1))) 924 925 (pass-if "definition of an already defined symbol" 926 (let* ((local (make-leaf-environment)) 927 (imported (make-leaf-environment)) 928 (env (make-eval-environment local imported))) 929 (environment-define env 'a 1) 930 (let* ((func (make-observer-func))) 931 (environment-observe-weak env func) 932 (environment-define env 'a 1) 933 (eqv? (func) 1)))) 934 935 (pass-if "set!ing of a defined symbol" 936 (let* ((local (make-leaf-environment)) 937 (imported (make-leaf-environment)) 938 (env (make-eval-environment local imported))) 939 (environment-define env 'a 1) 940 (let* ((func (make-observer-func))) 941 (environment-observe-weak env func) 942 (environment-set! env 'a 1) 943 (eqv? (func) 0)))) 944 945 (pass-if "undefining a defined symbol" 946 (let* ((local (make-leaf-environment)) 947 (imported (make-leaf-environment)) 948 (env (make-eval-environment local imported))) 949 (environment-define env 'a 1) 950 (let* ((func (make-observer-func))) 951 (environment-observe-weak env func) 952 (environment-undefine env 'a) 953 (eqv? (func) 1)))) 954 955 (pass-if "undefining an already undefined symbol" 956 (let* ((local (make-leaf-environment)) 957 (imported (make-leaf-environment)) 958 (env (make-eval-environment local imported)) 959 (func (make-observer-func))) 960 (environment-observe-weak env func) 961 (environment-undefine env 'a) 962 (eqv? (func) 0))) 963 964 (pass-if "unobserve an active observer" 965 (let* ((local (make-leaf-environment)) 966 (imported (make-leaf-environment)) 967 (env (make-eval-environment local imported)) 968 (func (make-observer-func)) 969 (observer (environment-observe-weak env func))) 970 (environment-unobserve observer) 971 (environment-define env 'a 1) 972 (eqv? (func) 0))) 973 974 (pass-if "unobserve an inactive observer" 975 (let* ((local (make-leaf-environment)) 976 (imported (make-leaf-environment)) 977 (env (make-eval-environment local imported)) 978 (func (make-observer-func)) 979 (observer (environment-observe-weak env func))) 980 (environment-unobserve observer) 981 (environment-unobserve observer) 982 #t)) 983 984 (pass-if "weak observer gets collected" 985 (gc) 986 (let* ((local (make-leaf-environment)) 987 (imported (make-leaf-environment)) 988 (env (make-eval-environment local imported)) 989 (func (make-observer-func))) 990 (environment-observe-weak env func) 991 (gc) 992 (environment-define env 'a 1) 993 (if (not (eqv? (func) 0)) 994 (throw 'unresolved) ; note: conservative scanning 995 #t)))) 996 997 998 (with-test-prefix "erroneous observers" 999 1000 (pass-if "update continues after error" 1001 (let* ((local (make-leaf-environment)) 1002 (imported (make-leaf-environment)) 1003 (env (make-eval-environment local imported)) 1004 (func-1 (make-erroneous-observer-func)) 1005 (func-2 (make-erroneous-observer-func))) 1006 (environment-observe env func-1) 1007 (environment-observe env func-2) 1008 (catch #t 1009 (lambda () 1010 (environment-define env 'a 1) 1011 #f) 1012 (lambda args 1013 (and (eq? (func-1) 1) 1014 (eq? (func-2) 1)))))))) 1015 1016 1017;;; 1018;;; leaf-environment based import-environments 1019;;; 1020 1021(with-test-prefix "leaf-environment based import-environments" 1022 1023 (with-test-prefix "import-environment?" 1024 1025 (pass-if "documented?" 1026 (documented? import-environment?)) 1027 1028 (pass-if "non-environment-object" 1029 (not (import-environment? #f))) 1030 1031 (pass-if "leaf-environment-object" 1032 (not (import-environment? (make-leaf-environment)))) 1033 1034 (pass-if "eval-environment-object" 1035 (let* ((local (make-leaf-environment)) 1036 (imported (make-leaf-environment)) 1037 (env (make-eval-environment local imported))) 1038 (not (import-environment? (make-leaf-environment)))))) 1039 1040 1041 (with-test-prefix "make-import-environment" 1042 1043 (pass-if "documented?" 1044 (documented? make-import-environment)))) 1045 1046