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

import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
@SuppressWarnings("PMD")
public class StringsTest {
    
    @Test
    public void testIndexOf() {
        assertEquals(-1, Strings.indexOf("", "z", 0));
        assertEquals(0, Strings.indexOf("", "", 0));
        assertEquals(0, Strings.indexOf("hello world", "", 0));
        assertEquals(-1, Strings.indexOf(null, "", 0));
        assertEquals(-1, Strings.indexOf("", null, 0));
        
        assertEquals(-1, Strings.indexOf("", "z", 5));
        assertEquals(0, Strings.indexOf("z", "z", 0));
        assertEquals(-1, Strings.indexOf("z", "ze", 0));

        assertEquals(4, Strings.indexOf("hello world", "o", 0));
        assertEquals(4, Strings.indexOf("hello world", "o", -32));
        assertEquals(4, Strings.indexOf("hello world", "o", 4));
        assertEquals(7, Strings.indexOf("hello world", "o", 5));
        assertEquals(7, Strings.indexOf("hello world", "o", 7));
        assertEquals(-1, Strings.indexOf("hello world", "o", 8));
        
        assertEquals(7, Strings.indexOf("hello world", "or", 0));
        assertEquals(7, Strings.indexOf("hello world", "or", -32));
        assertEquals(7, Strings.indexOf("hello world", "or", 7));
        assertEquals(-1, Strings.indexOf("hello world", "or", 8));
        
        assertEquals(-1, Strings.indexOf("hello world", "gam", 0));
        assertEquals(-1, Strings.indexOf("hello world", "gam", 8));
        assertEquals(-1, Strings.indexOf("hello world", "gam", 64));
    }
    
    @Test
    public void testIndexOfChar() {
        assertEquals(-1, Strings.indexOf("", 'z', 0));
        assertEquals(-1, Strings.indexOf("", 'z', 5));
        assertEquals(0, Strings.indexOf("z", 'z', 0));
        assertEquals(-1, Strings.indexOf(null, ' ', 0));

        assertEquals(4, Strings.indexOf("hello world", 'o', 0));
        assertEquals(4, Strings.indexOf("hello world", 'o', -32));
        assertEquals(4, Strings.indexOf("hello world", 'o', 4));
        assertEquals(7, Strings.indexOf("hello world", 'o', 5));
        assertEquals(7, Strings.indexOf("hello world", 'o', 7));
        assertEquals(-1, Strings.indexOf("hello world", 'o', 8));
        
        assertEquals(-1, Strings.indexOf("hello world", 'z', 0));
        assertEquals(-1, Strings.indexOf("hello world", 'z', 5));
        assertEquals(-1, Strings.indexOf("hello world", 'z', 64));
    }

    @Test
    public void testRaw() {
        assertEquals("hello", Strings.raw(/*hello*/));
        assertEquals("unique name", new Inner().name());
        assertEquals("value from anonymous", new Object(){
            @Override
            public String toString() {
                return Strings.raw(/*value from anonymous*/);
            }
        }.toString());
    }
    
    @Test
    public void testWrap() {
        char[] array = "hello".toCharArray();
        String text= Strings.wrap(array);

        // it works like ordinary string
        assertEquals("hello", text);
        
        // array is shared, not copied
        array[0] = 'H';
        assertEquals("Hello", text);
    }
    
    @Test
    public void testSubstring() {
        assertEquals("", Strings.substring(null, 0));
        assertEquals("", Strings.substring(null, -10));
        assertEquals("", Strings.substring(null, 10));
        
        assertEquals("hello", Strings.substring("hello", 0));
        assertEquals("hello", Strings.substring("hello", -10));
        assertEquals("llo", Strings.substring("hello", 2));
        assertEquals("", Strings.substring("hello", 10));
        
        assertEquals("", Strings.substring(null, 0, 0));
        assertEquals("", Strings.substring(null, 0, -10));
        assertEquals("", Strings.substring(null, -10, 0));
        assertEquals("", Strings.substring(null, -10,-20));
        assertEquals("", Strings.substring(null, -20,-10));
        assertEquals("", Strings.substring(null, 5,0));
        assertEquals("", Strings.substring(null, 0,5));
        
        assertEquals("", Strings.substring("hello", 0, 0));
        assertEquals("", Strings.substring("hello", 0, -10));
        assertEquals("", Strings.substring("hello", -10, 0));
        assertEquals("", Strings.substring("hello", -10,-20));
        assertEquals("", Strings.substring("hello", -20,-10));
        assertEquals("", Strings.substring("hello", 5, 0));
        
        assertEquals("hello", Strings.substring("hello", 0, 5));
        assertEquals("llo", Strings.substring("hello", 2, 5));
        assertEquals("l", Strings.substring("hello", 2, 3));
        assertEquals("", Strings.substring("hello", 2, 2));
        assertEquals("llo", Strings.substring("hello", 2, 50));
    }
    
    @Test
    public void testCompare() {
        assertTrue( Strings.compareTo(null, null) == 0 );
        assertTrue( Strings.compareTo(null, "")    < 0 );
        assertTrue( Strings.compareTo(null, "z")   < 0 );
        assertTrue( Strings.compareTo("", null)    > 0 );
        assertTrue( Strings.compareTo("z", null)   > 0 );
        assertTrue( Strings.compareTo("z", "z")   == 0 );
        
        assertTrue( Strings.compareTo("za", "zb")  < 0 );
        assertTrue( Strings.compareTo("zc", "zb")  > 0 );
    }
    
    @Test
    public void testAssigned() {
        assertTrue( Strings.isAssigned("a") );
        assertFalse( Strings.isAssigned("") );
        assertFalse( Strings.isAssigned(null) );
    }
    
    @Test
    public void testContains() {
        assertFalse( Strings.contains(null, "a") );
        assertFalse( Strings.contains("", "a") );
        assertFalse( Strings.contains("", null) );
        
        assertFalse( Strings.contains(null, "") );
        assertTrue(  Strings.contains("", "") );
        assertFalse( Strings.contains("text", null) );
        assertTrue(  Strings.contains("text", "") );
        
        assertFalse( Strings.contains("ret", "a") );
        assertTrue(  Strings.contains("rat", "a") );
        
        
        assertFalse( Strings.contains(null, 'a') );
        assertFalse( Strings.contains("", 'a') );
        assertFalse( Strings.contains("ret", 'a') );
        assertTrue(  Strings.contains("rat", 'a') );
    }
    
    @Test
    public void testLength() {
        assertEquals(0, Strings.length(null) );
        assertEquals(0, Strings.length("") );
        assertEquals(1, Strings.length("a") );
        assertEquals(5, Strings.length("hello") );
    }
    
    @Test
    public void testIsEqual() {
        assertTrue( Strings.isEqual(null, null) );
        assertTrue( Strings.isEqual("", "") );
        
        assertFalse( Strings.isEqual(null, "") );
        assertFalse( Strings.isEqual("", null) );
        
        assertTrue( Strings.isEqual("a", "a") );
        assertFalse( Strings.isEqual("a", "b") );
    }
    
    private class Inner {
        public String name() {
            return Strings.raw(/*unique name*/);
        }
    }
    
    @Test 
    public void testOR() {
        Object nval = null;
        Object eval = "";
        Object sval = new String("");
        
        assertSame(nval, Strings.or(nval) );
        assertSame(nval, Strings.or(null, null, nval) );
        
        assertSame(eval, Strings.or(eval) );
        assertSame(eval, Strings.or(null, eval) );
        assertSame(eval, Strings.or(null, eval, sval) );
        
        assertSame(sval, Strings.or(sval) );
        assertSame(sval, Strings.or(null, sval) );
        assertSame(sval, Strings.or(null, sval, eval) );
        
        assertEquals("?", Strings.or("?") );
        assertEquals("?", Strings.or(nval, "?") );
        assertEquals("?", Strings.or(null, null, nval, "?") );
        
        assertEquals("?", Strings.or(null, eval, "?") );
        assertEquals("?", Strings.or(null, eval, sval, "?") );
        
        assertEquals("?", Strings.or(sval, "?") );
        assertEquals("?", Strings.or(null, sval, "?") );
        assertEquals("?", Strings.or(null, sval, eval, "?") );
        
        assertEquals("?", Strings.or("?", nval) );
        assertEquals("?", Strings.or("?", eval) );
        assertEquals("?", Strings.or("?", sval) );
    }

}
