* Improved and enhanced the environment test suite.
authorDirk Herrmann <dirk@dirk-herrmanns-seiten.de>
Tue, 5 Sep 2000 10:49:10 +0000 (10:49 +0000)
committerDirk Herrmann <dirk@dirk-herrmanns-seiten.de>
Tue, 5 Sep 2000 10:49:10 +0000 (10:49 +0000)
test-suite/ChangeLog
test-suite/tests/environments.test

index 2bac129..665e1fd 100644 (file)
@@ -1,3 +1,10 @@
+2000-09-05  Dirk Herrmann  <D.Herrmann@tu-bs.de>
+
+       * tests/environments.test:  Finished and cleaned up the tests for
+       the leaf environments.  Added a complete set of testcases for the
+       leaf environment based eval environments.  Started with the tests
+       for the import environments.
+
 2000-08-25  Dirk Herrmann  <D.Herrmann@tu-bs.de>
 
        * tests/environments.test:  Added.
index 42e72e2..8f1f56b 100644 (file)
 (define (documented? object)
   (object-documentation object))
 
-(define (make-adder)
-  (let* ((counter 0))
-    (lambda increment
-      (if (not (null? increment))
-         (set! counter (+ counter (car increment))))
-      counter)))
-
 (define (folder sym val res)
   (cons (cons sym val) res))
 
+(define (make-observer-func)
+  (let* ((counter 0))
+    (lambda args
+      (if (null? args) 
+         counter
+         (set! counter (+ counter 1))))))
+
+(define (make-erroneous-observer-func)
+  (let* ((func (make-observer-func)))
+    (lambda args
+      (if (null? args) 
+         (func)
+         (begin 
+           (func args)
+           (error))))))
 
 ;;;
 ;;; leaf-environments
 
   (with-test-prefix "bound, define, ref, set!, cell"
 
-    (let* ((env (make-leaf-environment))
-          (ctr (make-adder)))
-
-      (pass-if "unbound by default"
+    (pass-if "symbols are unbound by default"
+      (let* ((env (make-leaf-environment)))
        (and (not (environment-bound? env 'a))
             (not (environment-bound? env 'b))
-            (not (environment-bound? env 'c))))
-
-      (pass-if "bound after define"
-       (environment-define env 'a (ctr 1))
-       (environment-bound? env 'a))
-
-      (pass-if "ref defined"
-       (and (begin
-              (environment-define env 'a (ctr 1))
-              (eq? (environment-ref env 'a) (ctr)))
-            (begin
-              (environment-define env 'a (ctr 1))
-              (eq? (environment-ref env 'a) (ctr)))))
-
-      (pass-if "set! defined"
-       (and (begin
-              (environment-set! env 'a (ctr 1))
-              (eq? (environment-ref env 'a) (ctr)))
-            (begin
-              (environment-set! env 'a (ctr 1))
-              (eq? (environment-ref env 'a) (ctr)))))
-
-      (pass-if "read-only cell"
+            (not (environment-bound? env 'c)))))
+
+    (pass-if "symbol is bound after define"
+      (let* ((env (make-leaf-environment)))
+       (environment-bound? env 'a)
+       (environment-define env 'a #t)
+       (environment-bound? env 'a)))
+
+    (pass-if "ref a defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-bound? env 'a)
+       (environment-bound? env 'b)
+       (environment-define env 'a #t)
+       (environment-define env 'b #f)
+       (and (environment-ref env 'a)
+            (not (environment-ref env 'b)))))
+
+    (pass-if "set! a defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a #t)
+       (environment-define env 'b #f)
+       (environment-ref env 'a)
+       (environment-ref env 'b)
+       (environment-set! env 'a #f)
+       (environment-set! env 'b #t)
+       (and (not (environment-ref env 'a))
+            (environment-ref env 'b))))
+
+    (pass-if "get a read-only cell"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a #t)
        (let* ((cell (environment-cell env 'a #f)))
-         (and (begin
-                (environment-set! env 'a (ctr 1))
-                (eq? (cdr cell) (ctr))))))
+         (and (cdr cell)
+              (begin
+                (environment-set! env 'a #f)
+                (not (cdr cell)))))))
 
-      (pass-if "read-only cell rebound after define"
+    (pass-if "a read-only cell gets rebound after define"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a #t)
        (let* ((cell (environment-cell env 'a #f)))
-         (environment-define env 'a (ctr 1))
-         (not (eq? (environment-cell env 'a #f) cell))))
+         (environment-define env 'a #f)
+         (not (eq? (environment-cell env 'a #f) cell)))))
 
-      (pass-if "writable cell"
+    (pass-if "get a writable cell"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a #t)
        (let* ((readable (environment-cell env 'a #f))
               (writable (environment-cell env 'a #t)))
          (and (eq? readable writable)
               (begin
-                (environment-set! env 'a (ctr 1))
-                (eq? (cdr writable) (ctr)))
+                (environment-set! env 'a #f)
+                (not (cdr writable)))
               (begin
-                (set-cdr! writable (ctr 1))
-                (eq? (environment-ref env 'a) (ctr)))
+                (set-cdr! writable #t)
+                (environment-ref env 'a))
               (begin
-                (set-cdr! (environment-cell env 'a #t) (ctr 1))
-                (eq? (cdr writable) (ctr))))))
+                (set-cdr! (environment-cell env 'a #t) #f)
+                (not (cdr writable)))))))
 
-      (pass-if "writable cell rebound after define"
+    (pass-if "a writable cell gets rebound after define"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a #t)
        (let* ((cell (environment-cell env 'a #t)))
-         (environment-define env 'a (ctr 1))
-         (not (eq? (environment-cell env 'a #t) cell))))
+         (environment-define env 'a #f)
+         (not (eq? (environment-cell env 'a #t) cell)))))
+
+    (pass-if "reference an undefined symbol"
+      (catch #t
+       (lambda ()
+         (environment-ref (make-leaf-environment) 'a)
+         #f)
+       (lambda args
+         #t)))
+
+    (pass-if "set! an undefined symbol"
+      (catch #t
+       (lambda ()
+         (environment-set! (make-leaf-environment) 'a)
+         #f)
+       (lambda args
+         #t)))
+
+    (pass-if "get a readable cell for an undefined symbol"
+      (catch #t
+       (lambda ()
+         (environment-cell (make-leaf-environment) 'a #f)
+         #f)
+       (lambda args
+         #t)))
+
+    (pass-if "get a writable cell for an undefined symbol"
+      (catch #t
+       (lambda ()
+         (environment-cell (make-leaf-environment) 'a #t)
+         #f)
+       (lambda args
+         #t))))
+
+
+  (with-test-prefix "undefine"
+
+    (pass-if "undefine a defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a 1)
+       (environment-ref env 'a)
+       (environment-undefine env 'a)
+       (not (environment-bound? env 'a))))
 
-      (pass-if "referencing undefined"
+    (pass-if "undefine an already undefined symbol"
+      (environment-undefine (make-leaf-environment) 'a)
+      #t))
+
+
+  (with-test-prefix "fold"
+
+    (pass-if "empty environment"
+      (let* ((env (make-leaf-environment)))
+       (eq? 'success (environment-fold env folder 'success))))
+
+    (pass-if "one symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a #t)
+       (equal? '((a . #t)) (environment-fold env folder '()))))
+
+    (pass-if "two symbols"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a #t)
+       (environment-define env 'b #f)
+       (let ((folded (environment-fold env folder '())))
+         (or (equal? folded '((a . #t) (b . #f)))
+             (equal? folded '((b . #f) (a . #t))))))))
+
+
+  (with-test-prefix "observe"
+
+    (pass-if "observe an environment"
+      (let* ((env (make-leaf-environment)))
+       (environment-observe env (make-observer-func))
+       #t))
+
+    (pass-if "observe an environment twice"
+      (let* ((env (make-leaf-environment))
+            (observer-1 (environment-observe env (make-observer-func)))
+            (observer-2 (environment-observe env (make-observer-func))))
+       (not (eq? observer-1 observer-2))))
+
+    (pass-if "definition of an undefined symbol"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func)))
+       (environment-observe env func)
+       (environment-define env 'a 1)
+       (eqv? (func) 1)))
+
+    (pass-if "definition of an already defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe env func)
+         (environment-define env 'a 1)
+         (eqv? (func) 1))))
+
+    (pass-if "set!ing of a defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe env func)
+         (environment-set! env 'a 1)
+         (eqv? (func) 0))))
+
+    (pass-if "undefining a defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe env func)
+         (environment-undefine env 'a)
+         (eqv? (func) 1))))
+
+    (pass-if "undefining an already undefined symbol"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func)))
+       (environment-observe env func)
+       (environment-undefine env 'a)
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an active observer"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func))
+            (observer (environment-observe env func)))
+       (environment-unobserve observer)
+       (environment-define env 'a 1)
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an inactive observer"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func))
+            (observer (environment-observe env func)))
+       (environment-unobserve observer)
+       (environment-unobserve observer)
+       #t)))
+
+
+  (with-test-prefix "observe-weak"
+
+    (pass-if "observe an environment"
+      (let* ((env (make-leaf-environment)))
+       (environment-observe-weak env (make-observer-func))
+       #t))
+
+    (pass-if "observe an environment twice"
+      (let* ((env (make-leaf-environment))
+            (observer-1 (environment-observe-weak env (make-observer-func)))
+            (observer-2 (environment-observe-weak env (make-observer-func))))
+       (not (eq? observer-1 observer-2))))
+
+    (pass-if "definition of an undefined symbol"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func)))
+       (environment-observe-weak env func)
+       (environment-define env 'a 1)
+       (eqv? (func) 1)))
+
+    (pass-if "definition of an already defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe-weak env func)
+         (environment-define env 'a 1)
+         (eqv? (func) 1))))
+
+    (pass-if "set!ing of a defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe-weak env func)
+         (environment-set! env 'a 1)
+         (eqv? (func) 0))))
+
+    (pass-if "undefining a defined symbol"
+      (let* ((env (make-leaf-environment)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe-weak env func)
+         (environment-undefine env 'a)
+         (eqv? (func) 1))))
+
+    (pass-if "undefining an already undefined symbol"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func)))
+       (environment-observe-weak env func)
+       (environment-undefine env 'a)
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an active observer"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func))
+            (observer (environment-observe-weak env func)))
+       (environment-unobserve observer)
+       (environment-define env 'a 1)
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an inactive observer"
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func))
+            (observer (environment-observe-weak env func)))
+       (environment-unobserve observer)
+       (environment-unobserve observer)
+       #t))
+
+    (pass-if "weak observer gets collected"
+      (gc)
+      (let* ((env (make-leaf-environment))
+            (func (make-observer-func)))
+       (environment-observe-weak env func)
+       (gc)
+       (environment-define env 'a 1)
+       (eqv? (func) 0))))
+
+
+  (with-test-prefix "erroneous observers"
+
+    (pass-if "update continues after error"
+      (let* ((env (make-leaf-environment))
+            (func-1 (make-erroneous-observer-func))
+            (func-2 (make-erroneous-observer-func)))
+       (environment-observe env func-1)
+       (environment-observe env func-2)
+       (catch #t
+         (lambda () 
+           (environment-define env 'a 1)
+           #f)
+         (lambda args
+           (and (eq? (func-1) 1) 
+                (eq? (func-2) 1))))))))
+
+
+;;;
+;;; leaf-environment based eval-environments
+;;;
+
+(with-test-prefix "leaf-environment based eval-environments"
+
+  (with-test-prefix "eval-environment?"
+
+    (pass-if "documented?"
+      (documented? eval-environment?))
+
+    (pass-if "non-environment-object"
+      (not (eval-environment? #f)))
+
+    (pass-if "leaf-environment-object"
+      (not (eval-environment? (make-leaf-environment)))))
+
+
+  (with-test-prefix "make-eval-environment"
+
+    (pass-if "documented?"
+      (documented? make-eval-environment))
+
+    (let* ((local (make-leaf-environment))
+          (imported (make-leaf-environment)))
+
+      (pass-if "produces an environment"
+       (environment? (make-eval-environment local imported)))
+
+      (pass-if "produces an eval-environment"
+       (eval-environment? (make-eval-environment local imported)))
+
+      (pass-if "produces always a new environment"
+       (not (eq? (make-eval-environment local imported)
+                 (make-eval-environment local imported))))))
+
+
+  (with-test-prefix "eval-environment-local"
+
+    (pass-if "documented?"
+      (documented? eval-environment-local))
+
+    (pass-if "returns local"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (eq? (eval-environment-local env) local))))
+
+
+  (with-test-prefix "eval-environment-imported"
+
+    (pass-if "documented?"
+      (documented? eval-environment-imported))
+
+    (pass-if "returns imported"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (eq? (eval-environment-imported env) imported))))
+
+
+  (with-test-prefix "bound, define, ref, set!, cell"
+
+    (pass-if "symbols are unbound by default"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (and (not (environment-bound? env 'a))
+            (not (environment-bound? env 'b))
+            (not (environment-bound? env 'c)))))
+
+    (with-test-prefix "symbols bound in imported"
+
+      (pass-if "binding is visible"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-bound? env 'a)
+         (environment-define imported 'a #t)
+         (environment-bound? env 'a)))
+
+      (pass-if "ref works"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-bound? env 'a)
+         (environment-define imported 'a #t)
+         (environment-ref env 'a)))
+
+      (pass-if "set! works"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define imported 'a #f)
+         (environment-set! env 'a #t)
+         (environment-ref imported 'a)))
+
+      (pass-if "cells are passed through"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define imported 'a #t)
+         (let* ((imported-cell (environment-cell imported 'a #f))
+                (env-cell (environment-cell env 'a #f)))
+           (eq? env-cell imported-cell)))))
+
+    (with-test-prefix "symbols bound in local"
+
+      (pass-if "binding is visible"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-bound? env 'a)
+         (environment-define local 'a #t)
+         (environment-bound? env 'a)))
+
+      (pass-if "ref works"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define local 'a #t)
+         (environment-ref env 'a)))
+
+      (pass-if "set! works"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define local 'a #f)
+         (environment-set! env 'a #t)
+         (environment-ref local 'a)))
+
+      (pass-if "cells are passed through"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define local 'a #t)
+         (let* ((local-cell (environment-cell local 'a #f))
+                (env-cell (environment-cell env 'a #f)))
+           (eq? env-cell local-cell)))))
+
+    (with-test-prefix "symbols bound in local and imported"
+
+      (pass-if "binding is visible"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-bound? env 'a)
+         (environment-define imported 'a #t)
+         (environment-define local 'a #f)
+         (environment-bound? env 'a)))
+
+      (pass-if "ref works"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define imported 'a #f)
+         (environment-define local 'a #t)
+         (environment-ref env 'a)))
+
+      (pass-if "set! changes local"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define imported 'a #f)
+         (environment-define local 'a #f)
+         (environment-set! env 'a #t)
+         (environment-ref local 'a)))
+
+      (pass-if "set! does not touch imported"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define imported 'a #t)
+         (environment-define local 'a #t)
+         (environment-set! env 'a #f)
+         (environment-ref imported 'a)))
+
+      (pass-if "cells from local are passed through"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define local 'a #t)
+         (let* ((local-cell (environment-cell local 'a #f))
+                (env-cell (environment-cell env 'a #f)))
+           (eq? env-cell local-cell)))))
+
+    (with-test-prefix "defining symbols"
+
+      (pass-if "symbols are bound in local after define"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define env 'a #t)
+         (environment-bound? local 'a)))
+
+      (pass-if "cells in local get rebound after define"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define env 'a #f)
+         (let* ((old-cell (environment-cell local 'a #f)))
+           (environment-define env 'a #f)
+           (let* ((new-cell (environment-cell local 'a #f)))
+             (not (eq? new-cell old-cell))))))
+
+      (pass-if "cells in imported get shadowed after define"
+       (let* ((local (make-leaf-environment))
+              (imported (make-leaf-environment))
+              (env (make-eval-environment local imported)))
+         (environment-define imported 'a #f)
+         (environment-define env 'a #t)
+         (environment-ref local 'a))))
+
+    (let* ((local (make-leaf-environment))
+          (imported (make-leaf-environment))
+          (env (make-eval-environment local imported)))
+
+      (pass-if "reference an undefined symbol"
        (catch #t
          (lambda ()
            (environment-ref env 'b)
          (lambda args
            #t)))
 
-      (pass-if "set!ing undefined"
+      (pass-if "set! an undefined symbol"
        (catch #t
          (lambda ()
            (environment-set! env 'b)
          (lambda args
            #t)))
 
-      (pass-if "readable cell from undefined"
+      (pass-if "get a readable cell for an undefined symbol"
        (catch #t
          (lambda ()
            (environment-cell env 'b #f)
          (lambda args
            #t)))
 
-      (pass-if "writable cell from undefined"
+      (pass-if "get a writable cell for an undefined symbol"
        (catch #t
          (lambda ()
            (environment-cell env 'b #t)
          (lambda args
            #t)))))
 
+  (with-test-prefix "eval-environment-set-local!"
 
-  (with-test-prefix "undefine"
-
-    (let* ((env (make-leaf-environment)))
-
-      (pass-if "undefine defined"
-       (environment-define env 'a 1)
-       (and (environment-bound? env 'a)
-            (begin
-              (environment-undefine env 'a)
-              (not (environment-bound? env 'a)))))
-
-      (pass-if "undefine undefined"
-       (and (not (environment-bound? env 'a))
-            (begin
-              (environment-undefine env 'a)
-              (not (environment-bound? env 'a)))))))
+    (pass-if "documented?"
+      (documented? eval-environment-set-local!))
+
+    (pass-if "new binding becomes visible"
+      (let* ((old-local (make-leaf-environment))
+            (new-local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment old-local imported)))
+       (environment-bound? env 'a)
+       (environment-define new-local 'a #t)
+       (eval-environment-set-local! env new-local)
+       (environment-bound? env 'a)))
+
+    (pass-if "existing binding is replaced"
+      (let* ((old-local (make-leaf-environment))
+            (new-local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment old-local imported)))
+       (environment-define old-local 'a #f)
+       (environment-ref env 'a)
+       (environment-define new-local 'a #t)
+       (eval-environment-set-local! env new-local)
+       (environment-ref env 'a)))
+
+    (pass-if "undefined binding is removed"
+      (let* ((old-local (make-leaf-environment))
+            (new-local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment old-local imported)))
+       (environment-define old-local 'a #f)
+       (environment-ref env 'a)
+       (eval-environment-set-local! env new-local)
+       (not (environment-bound? env 'a))))
+
+    (pass-if "binding in imported remains shadowed"
+      (let* ((old-local (make-leaf-environment))
+            (new-local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment old-local imported)))
+       (environment-define imported 'a #f)
+       (environment-define old-local 'a #f)
+       (environment-ref env 'a)
+       (environment-define new-local 'a #t)
+       (eval-environment-set-local! env new-local)
+       (environment-ref env 'a)))
+
+    (pass-if "binding in imported gets shadowed"
+      (let* ((old-local (make-leaf-environment))
+            (new-local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment old-local imported)))
+       (environment-define imported 'a #f)
+       (environment-ref env 'a)
+       (environment-define new-local 'a #t)
+       (eval-environment-set-local! env new-local)
+       (environment-ref env 'a)))
+
+    (pass-if "binding in imported becomes visible"
+      (let* ((old-local (make-leaf-environment))
+            (new-local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment old-local imported)))
+       (environment-define imported 'a #t)
+       (environment-define old-local 'a #f)
+       (environment-ref env 'a)
+       (eval-environment-set-local! env new-local)
+       (environment-ref env 'a))))
+
+  (with-test-prefix "eval-environment-set-imported!"
 
+    (pass-if "documented?"
+      (documented? eval-environment-set-imported!))
+
+    (pass-if "new binding becomes visible"
+      (let* ((local (make-leaf-environment))
+            (old-imported (make-leaf-environment))
+            (new-imported (make-leaf-environment))
+            (env (make-eval-environment local old-imported)))
+       (environment-bound? env 'a)
+       (environment-define new-imported 'a #t)
+       (eval-environment-set-imported! env new-imported)
+       (environment-bound? env 'a)))
+
+    (pass-if "existing binding is replaced"
+      (let* ((local (make-leaf-environment))
+            (old-imported (make-leaf-environment))
+            (new-imported (make-leaf-environment))
+            (env (make-eval-environment local old-imported)))
+       (environment-define old-imported 'a #f)
+       (environment-ref env 'a)
+       (environment-define new-imported 'a #t)
+       (eval-environment-set-imported! env new-imported)
+       (environment-ref env 'a)))
+
+    (pass-if "undefined binding is removed"
+      (let* ((local (make-leaf-environment))
+            (old-imported (make-leaf-environment))
+            (new-imported (make-leaf-environment))
+            (env (make-eval-environment local old-imported)))
+       (environment-define old-imported 'a #f)
+       (environment-ref env 'a)
+       (eval-environment-set-imported! env new-imported)
+       (not (environment-bound? env 'a))))
+
+    (pass-if "binding in imported remains shadowed"
+      (let* ((local (make-leaf-environment))
+            (old-imported (make-leaf-environment))
+            (new-imported (make-leaf-environment))
+            (env (make-eval-environment local old-imported)))
+       (environment-define local 'a #t)
+       (environment-define old-imported 'a #f)
+       (environment-ref env 'a)
+       (environment-define new-imported 'a #t)
+       (eval-environment-set-imported! env new-imported)
+       (environment-ref env 'a)))
+
+    (pass-if "binding in imported gets shadowed"
+      (let* ((local (make-leaf-environment))
+            (old-imported (make-leaf-environment))
+            (new-imported (make-leaf-environment))
+            (env (make-eval-environment local old-imported)))
+       (environment-define local 'a #t)
+       (environment-ref env 'a)
+       (environment-define new-imported 'a #f)
+       (eval-environment-set-imported! env new-imported)
+       (environment-ref env 'a))))
 
-  (with-test-prefix "fold"
+  (with-test-prefix "undefine"
 
-    (let* ((env (make-leaf-environment))
-          (ctr (make-adder)))
+    (pass-if "undefine an already undefined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-undefine env 'a)
+       #t))
 
-      (pass-if "fold empty"
-       (eq? 'success (environment-fold env folder 'success)))
+    (pass-if "undefine removes a binding from local"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define local 'a #t)
+       (environment-undefine env 'a)
+       (not (environment-bound? local 'a))))
 
-      (pass-if "after define"
-       (environment-define env 'a (ctr 1))
-       (equal? `((a . ,(ctr))) (environment-fold env folder '())))
+    (pass-if "undefine does not influence imported"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define imported 'a #t)
+       (environment-undefine env 'a)
+       (environment-bound? imported 'a)))
 
-      (pass-if "after undefine"
+    (pass-if "undefine an imported symbol does not undefine it"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define imported 'a #t)
        (environment-undefine env 'a)
-       (eq? 'success (environment-fold env folder 'success)))
+       (environment-bound? env 'a)))
+
+    (pass-if "undefine unshadows an imported symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define imported 'a #t)
+       (environment-define local 'a #f)
+       (environment-undefine env 'a)
+       (environment-ref env 'a))))
 
-      (pass-if "after two defines"
-       (let* ((i (ctr 1))
-              (j (+ i 1)))
-         (environment-define env 'a i)
-         (environment-define env 'b j)
-         (let ((folded (environment-fold env folder '())))
-           (or (equal? folded `((a . ,i) (b . ,j)))
-               (equal? folded `((b . ,j) (a . ,i)))))))
+  (with-test-prefix "fold"
 
-      (pass-if "after set!"
-       (let* ((i (environment-ref env 'a)))
-         (environment-set! env 'b i)
-         (let ((folded (environment-fold env folder '())))
-           (or (equal? folded `((a . ,i) (b . ,i)))
-               (equal? folded `((b . ,i) (a . ,i)))))))))
+    (pass-if "empty environment"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (eq? 'success (environment-fold env folder 'success))))
+
+    (pass-if "one symbol in local"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define local 'a #t)
+       (equal? '((a . #t)) (environment-fold env folder '()))))
+
+    (pass-if "one symbol in imported"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define imported 'a #t)
+       (equal? '((a . #t)) (environment-fold env folder '()))))
+
+    (pass-if "shadowed symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define local 'a #t)
+       (environment-define imported 'a #f)
+       (equal? '((a . #t)) (environment-fold env folder '()))))
+
+    (pass-if "one symbol each"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define local 'a #t)
+       (environment-define imported 'b #f)
+       (let ((folded (environment-fold env folder '())))
+         (or (equal? folded '((a . #t) (b . #f)))
+             (equal? folded '((b . #f) (a . #t))))))))
 
 
   (with-test-prefix "observe"
 
-    (let* ((env (make-leaf-environment))
-          (tag #f)
-          (func (lambda (env) (set! tag (not tag))))
-          (observer #f))
-
-      (pass-if "observe unobserved"
-       (set! observer (environment-observe env func))
-       #t)
-
-      (pass-if "define undefined"
-       (set! tag #f)
+    (pass-if "observe an environment"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-observe env (make-observer-func))
+       #t))
+
+    (pass-if "observe an environment twice"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (observer-1 (environment-observe env (make-observer-func)))
+            (observer-2 (environment-observe env (make-observer-func))))
+       (not (eq? observer-1 observer-2))))
+
+    (pass-if "definition of an undefined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func)))
+       (environment-observe env func)
        (environment-define env 'a 1)
-       tag)
+       (eqv? (func) 1)))
 
-      (pass-if "define defined"
-       (set! tag #f)
+    (pass-if "definition of an already defined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
        (environment-define env 'a 1)
-       tag)
-
-      (pass-if "set! defined"
-       (set! tag #t)
-       (environment-set! env 'a 1)
-       tag)
-
-      (pass-if "undefine defined"
-       (set! tag #f)
-       (environment-undefine env 'a)
-       tag)
-
-      (pass-if "undefine undefined"
-       (set! tag #t)
+       (let* ((func (make-observer-func)))
+         (environment-observe env func)
+         (environment-define env 'a 1)
+         (eqv? (func) 1))))
+
+    (pass-if "set!ing of a defined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe env func)
+         (environment-set! env 'a 1)
+         (eqv? (func) 0))))
+
+    (pass-if "undefining a defined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe env func)
+         (environment-undefine env 'a)
+         (eqv? (func) 1))))
+
+    (pass-if "undefining an already undefined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func)))
+       (environment-observe env func)
        (environment-undefine env 'a)
-       tag)
-
-      (pass-if "unobserve observed"
-       (set! tag #t)
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an active observer"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func))
+            (observer (environment-observe env func)))
        (environment-unobserve observer)
        (environment-define env 'a 1)
-       tag)
-
-      (pass-if "unobserve unobserved"
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an inactive observer"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func))
+            (observer (environment-observe env func)))
+       (environment-unobserve observer)
        (environment-unobserve observer)
        #t)))
 
 
   (with-test-prefix "observe-weak"
 
-    (let* ((env (make-leaf-environment))
-          (tag #f)
-          (func (lambda (env) (set! tag (not tag))))
-          (observer #f))
-
-      (pass-if "weak-observe unobserved"
-       (set! observer (environment-observe-weak env func))
-       #t)
-
-      (pass-if "define undefined"
-       (set! tag #f)
+    (pass-if "observe an environment"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-observe-weak env (make-observer-func))
+       #t))
+
+    (pass-if "observe an environment twice"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (observer-1 (environment-observe-weak env (make-observer-func)))
+            (observer-2 (environment-observe-weak env (make-observer-func))))
+       (not (eq? observer-1 observer-2))))
+
+    (pass-if "definition of an undefined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func)))
+       (environment-observe-weak env func)
        (environment-define env 'a 1)
-       tag)
+       (eqv? (func) 1)))
 
-      (pass-if "define defined"
-       (set! tag #f)
+    (pass-if "definition of an already defined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
        (environment-define env 'a 1)
-       tag)
-
-      (pass-if "set! defined"
-       (set! tag #t)
-       (environment-set! env 'a 1)
-       tag)
-
-      (pass-if "undefine defined"
-       (set! tag #f)
-       (environment-undefine env 'a)
-       tag)
-
-      (pass-if "undefine undefined"
-       (set! tag #t)
+       (let* ((func (make-observer-func)))
+         (environment-observe-weak env func)
+         (environment-define env 'a 1)
+         (eqv? (func) 1))))
+
+    (pass-if "set!ing of a defined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe-weak env func)
+         (environment-set! env 'a 1)
+         (eqv? (func) 0))))
+
+    (pass-if "undefining a defined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (environment-define env 'a 1)
+       (let* ((func (make-observer-func)))
+         (environment-observe-weak env func)
+         (environment-undefine env 'a)
+         (eqv? (func) 1))))
+
+    (pass-if "undefining an already undefined symbol"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func)))
+       (environment-observe-weak env func)
        (environment-undefine env 'a)
-       tag)
-
-      (pass-if "unobserve observed"
-       (set! tag #t)
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an active observer"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func))
+            (observer (environment-observe-weak env func)))
        (environment-unobserve observer)
        (environment-define env 'a 1)
-       tag)
-
-      (pass-if "unobserve unobserved"
+       (eqv? (func) 0)))
+
+    (pass-if "unobserve an inactive observer"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func))
+            (observer (environment-observe-weak env func)))
        (environment-unobserve observer)
-       #t)
-
-      (pass-if "weak observer gets collected"
-       (gc)
+       (environment-unobserve observer)
+       #t))
+
+    (pass-if "weak observer gets collected"
+      (gc)
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func (make-observer-func)))
        (environment-observe-weak env func)
-       (set! tag #f)
+       (gc)
        (environment-define env 'a 1)
-       (and tag
-            (begin
-              (gc)
-              (environment-define env 'a 1)
-              tag)))))
-
-
-  (with-test-prefix "observer-errors"
-
-    (let* ((env (make-leaf-environment))
-          (tag-1 #f)
-          (tag-2 #f)
-          (func-1 (lambda (env) 
-                    (set! tag-1 (not tag-1))
-                    (error)))
-          (func-2 (lambda (env)
-                    (set! tag-2 (not tag-2))
-                    (error))))
-
-      (pass-if "update continues after error"
+       (eqv? (func) 0))))
+
+
+  (with-test-prefix "erroneous observers"
+
+    (pass-if "update continues after error"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported))
+            (func-1 (make-erroneous-observer-func))
+            (func-2 (make-erroneous-observer-func)))
        (environment-observe env func-1)
        (environment-observe env func-2)
        (catch #t
            (environment-define env 'a 1)
            #f)
          (lambda args
-           (and tag-1 tag-2)))))))
\ No newline at end of file
+           (and (eq? (func-1) 1) 
+                (eq? (func-2) 1))))))))
+
+
+;;;
+;;; leaf-environment based import-environments
+;;;
+
+(with-test-prefix "leaf-environment based import-environments"
+
+  (with-test-prefix "import-environment?"
+
+    (pass-if "documented?"
+      (documented? import-environment?))
+
+    (pass-if "non-environment-object"
+      (not (import-environment? #f)))
+
+    (pass-if "leaf-environment-object"
+      (not (import-environment? (make-leaf-environment))))
+
+    (pass-if "eval-environment-object"
+      (let* ((local (make-leaf-environment))
+            (imported (make-leaf-environment))
+            (env (make-eval-environment local imported)))
+       (not (import-environment? (make-leaf-environment))))))
+
+
+  (with-test-prefix "make-import-environment"
+
+    (pass-if "documented?"
+      (documented? make-import-environment))))
+