/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.reflection.inspect;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.ranides.assira.collection.SetUtils;
import net.ranides.assira.reflection.mock.Bean1;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class BeanInspectorTest {
    
    
    @Test
    public void testEmpty() {
        assertTrue( BeanInspector.forClass(null).properties().isEmpty());
        assertTrue( BeanInspector.forClass(Void.class).properties().isEmpty());
        assertTrue( BeanInspector.forClass(void.class).properties().isEmpty());
        
        assertTrue( BeanInspector.forObject(null).properties().isEmpty());
        assertTrue( BeanInspector.forObject(new Object()).properties().isEmpty());
    }
    
    @Test
    public void testRO() {
        BeanInspector model = BeanInspector.forClass(Bean1.class);
        Set<String> exp1 = SetUtils.asHashSet(
            "hello", "height", "width", "number", "name"
        );
        assertEquals(exp1, model.properties());
        
        assertTrue(model.isReadable("hello"));
        assertTrue(model.isReadable("height"));
        assertTrue(model.isReadable("width"));
        assertTrue(model.isReadable("number"));
        assertFalse(model.isReadable("name"));
        
        assertTrue(model.isWritable("hello"));
        assertTrue(model.isWritable("height"));
        assertFalse(model.isWritable("width"));
        assertFalse(model.isWritable("number"));
        assertTrue(model.isWritable("name"));
    }
    
    @Test
    public void testTypeof() {
        BeanInspector model = BeanInspector.forClass(Bean1.class);
        assertEquals("int", model.typeof("hello").toString());
        assertEquals("int", model.typeof("height").toString());
        assertEquals("int", model.typeof("width").toString());
        assertEquals("int", model.typeof("number").toString());
        assertEquals("String", model.typeof("name").toString());
    }

    @Test
    public void testEachList() {
        
        List<Bean1> items = new ArrayList<>(5);
        for(int i=0; i<5; i++) {
            items.add(new Bean1(i,10*i,100*i));
        }
        Bean1 item = items.get(3);
        
        BeanInspector model = BeanInspector.forObject(items.get(0));
        
        assertEquals("[0,100,200,300,400]", model.each(items, "hello").toString() );
        assertEquals("[0,10,20,30,40]", model.each(items, "height").toString() );                
        assertEquals("[0,1,2,3,4]", model.each(items, "width").toString() );
        
        List<Integer> items1  = (List)model.each(items, "hello");
        for(int i=0; i<items1.size(); i++) {
            items1.set(i, 1 + items1.get(i) );
        }
        assertEquals("[1,101,201,301,401]", model.each(items, "hello").toString() );
        
        assertEquals( (Integer)301, model.get(item, "hello"));
        assertEquals( (Integer)30, model.get(item, "height"));
        assertEquals( (Integer)3, model.get(item, "width"));
        
        model.put(item, "hello", 501);
        model.put(item, "height", 50);
        model.put(item, "width", 5);
        
        assertEquals( (Integer)501, model.get(item, "hello"));
        assertEquals( (Integer)50, model.get(item, "height"));
        assertEquals( (Integer)5, model.get(item, "width"));
    }
    
    @Test
    public void testEachCollection() {
        
        Collection<Bean1> items = new ArrayList<>(5);
        for(int i=0; i<5; i++) {
            items.add(new Bean1(i,10*i,100*i));
        }
        
        BeanInspector model = BeanInspector.forClass(Bean1.class);
        
        assertEquals("{0,100,200,300,400}", model.each(items, "hello").toString() );
        assertEquals("{0,10,20,30,40}", model.each(items, "height").toString() );                
        assertEquals("{0,1,2,3,4}", model.each(items, "width").toString() );
        
        Bean1 item = ((List<Bean1>)items).get(3);
        
        model.put(item, "hello", 501);
        model.put(item, "height", 50);
        model.put(item, "width", 5);
        
        assertEquals("{0,100,200,501,400}", model.each(items, "hello").toString() );
        assertEquals("{0,10,20,50,40}", model.each(items, "height").toString() );                
        assertEquals("{0,1,2,5,4}", model.each(items, "width").toString() );

    }
    
}
