// Path: src/main/java/com/timgroup/karg/reference/Getter.java
// public interface Getter<O, T> {
//     T get(O object);
// }
// 
// Path: src/main/java/com/timgroup/karg/reference/Lens.java
// public interface Lens<O, T> extends Getter<O, T>, Setter<O, T> { }


import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import org.junit.Test;
import com.timgroup.karg.reference.Getter;
import com.timgroup.karg.reference.Lens;
                            "hashCode", "class", "toString"));
    }
    
    @Test public void
    exposes_all_writable_attributes_of_a_class_as_lenses() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        assertThat(catalogue.allAttributes().keySet(),
                   hasItems("writableField", "encapsulatedField"));
    }
    
    @Test public void
    does_not_expose_read_only_attributes_of_a_class_as_lenses() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        assertThat(catalogue.allAttributes().keySet(),
                   not(hasItems("readOnlyField", "readOnlyProperty",
                                "hashCode", "class", "toString")));
    }
    
    @Test public void
    has_a_type_inferencing_getReadOnlyAttribute_method() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        Getter<TestClass, String> getter = catalogue.getReadOnlyAttribute("encapsulatedField");
        TestClass testInstance = new TestClass();
        assertThat(getter.get(testInstance), is("writable value 2"));
    }
    
    @Test public void
    has_a_type_inferencing_getAttribute_method() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        Lens<TestClass, String> lens = catalogue.getAttribute("encapsulatedField");
// Path: src/main/java/com/timgroup/karg/reference/Getter.java
// public interface Getter<O, T> {
//     T get(O object);
// }
// 
// Path: src/main/java/com/timgroup/karg/reference/Lens.java
// public interface Lens<O, T> extends Getter<O, T>, Setter<O, T> { }


// Path: src/test/java/com/timgroup/karg/reflection/AccessorCatalogueTest.java
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import org.junit.Test;
import com.timgroup.karg.reference.Getter;
import com.timgroup.karg.reference.Lens;

                            "hashCode", "class", "toString"));
    }
    
    @Test public void
    exposes_all_writable_attributes_of_a_class_as_lenses() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        assertThat(catalogue.allAttributes().keySet(),
                   hasItems("writableField", "encapsulatedField"));
    }
    
    @Test public void
    does_not_expose_read_only_attributes_of_a_class_as_lenses() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        assertThat(catalogue.allAttributes().keySet(),
                   not(hasItems("readOnlyField", "readOnlyProperty",
                                "hashCode", "class", "toString")));
    }
    
    @Test public void
    has_a_type_inferencing_getReadOnlyAttribute_method() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        Getter<TestClass, String> getter = catalogue.getReadOnlyAttribute("encapsulatedField");
        TestClass testInstance = new TestClass();
        assertThat(getter.get(testInstance), is("writable value 2"));
    }
    
    @Test public void
    has_a_type_inferencing_getAttribute_method() {
        AccessorCatalogue<TestClass> catalogue = AccessorCatalogue.forClass(TestClass.class);
        Lens<TestClass, String> lens = catalogue.getAttribute("encapsulatedField");
        TestClass testInstance = new TestClass();