package com.codepoetics.radioactive;

import com.google.common.collect.ImmutableMap;
import org.junit.Test;

import java.util.*;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

public class MappingTest {

    @Test public void
    mapping_from_map_to_map() {
        Map<String, String> left = ImmutableMap.of("foo", "bar");
        Map<String, String> right = new HashMap<>();

        Mapper.from(Getter.<String, String>fromMap("foo"))
              .to(Setter.<String, String>toMap("xyzzy"))
              .accept(left, right);

        assertThat(right.get("xyzzy"), equalTo("bar"));
    }

    public static class Person {
        private String name;
        private int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }

    public static class Knight extends Person {
        private String quest;

        public String getQuest() {
            return quest;
        }

        public void setQuest(String quest) {
            this.quest = quest;
        }
    }

    @Test public void
    mapping_from_bean_to_same_bean_class() {
        Person person1 = new Person();
        person1.setName("Antigone");
        person1.setAge(30);

        Person person2 = Mapper.from(Person::getAge).to(Person::setAge)
              .andFrom(Person::getName).to(Person::setName)
              .creatingWith(Person::new)
              .apply(person1);

        assertThat(person2.getName(), equalTo("Antigone"));
        assertThat(person2.getAge(), equalTo(30));
    }

    @Test public void
    mapping_from_bean_to_different_bean_class() {
        Person person1 = new Person();
        person1.setName("Antigone");
        person1.setAge(30);

        Knight bean2 = Mapper.from(Person::getAge).to(Knight::setAge)
                .andFrom(Person::getName).via(String::toUpperCase).to(Knight::setName)
                .andFrom("I seek the grail").to(Knight::setQuest)
                .creatingWith(Knight::new)
                .apply(person1);

        assertThat(bean2.getName(), equalTo("ANTIGONE"));
        assertThat(bean2.getAge(), equalTo(30));
        assertThat(bean2.getQuest(), equalTo("I seek the grail"));
    }

    @Test public void
    default_values() {
        Person person1 = new Person();
        person1.setAge(30);

        Knight bean2 = Mapper.from(Person::getAge).to(Knight::setAge)
                .andFrom(Getter.ofNullable(Person::getName).orElse("N/A")).to(Knight::setName)
                .andFrom("I seek the grail").to(Knight::setQuest)
                .creatingWith(Knight::new)
                .apply(person1);

        assertThat(bean2.getName(), equalTo("N/A"));
        assertThat(bean2.getAge(), equalTo(30));
        assertThat(bean2.getQuest(), equalTo("I seek the grail"));
    }
}

@@ -123,9 +123,73 @@
 til.
-*
+HashMap;%0Aimport java.util.Map;%0Aimport java.util.function.Supplier
 ;%0A%0Ai
@@ -1327,32 +1327,829 @@
 quest;%0A        %7D
+%0A%0A        public static class Builder implements Supplier%3CKnight%3E %7B%0A            private String name;%0A            private int age;%0A            private String quest;%0A%0A            public Builder withName(String name) %7B%0A                this.name = name;%0A                return this;%0A            %7D%0A%0A            public Builder withAge(int age) %7B%0A                this.age = age;%0A                return this;%0A            %7D%0A%0A            public Builder withQuest(String quest) %7B%0A                this.quest = quest;%0A                return this;%0A            %7D%0A%0A            public Knight get() %7B%0A                Knight knight = new Knight();%0A                knight.setName(name);%0A                knight.setAge(age);%0A                knight.setQuest(quest);%0A                return knight;%0A            %7D%0A        %7D
 %0A    %7D%0A%0A    @Tes
@@ -3706,32 +3706,32 @@
 pply(person1);%0A%0A
-
         assertTh
@@ -3888,11 +3888,704 @@
 );%0A    %7D
+%0A%0A    @Test public void%0A    mapping_with_builder() %7B%0A        Person person1 = new Person();%0A        person1.setName(%22Antigone%22);%0A        person1.setAge(30);%0A%0A        Knight bean2 = Mapper.from(Person::getAge).to(Knight.Builder::withAge)%0A                .andFrom(Person::getName).via(String::toUpperCase).to(Knight.Builder::withName)%0A                .andFrom(%22I seek the grail%22).to(Knight.Builder::withQuest)%0A                .creatingWith(Knight.Builder::new, Knight.Builder::get)%0A                .apply(person1);%0A%0A        assertThat(bean2.getName(), equalTo(%22ANTIGONE%22));%0A        assertThat(bean2.getAge(), equalTo(30));%0A        assertThat(bean2.getQuest(), equalTo(%22I seek the grail%22));%0A    %7D
 %0A%7D%0A

test mapping with a builder