getName() { return Optional.ofNullable(name); } private boolean isNameEquals(String otherName) { final String thisName = getName().orElse("#"+otherName); return thisN"> getName() { return Optional.ofNullable(name); } private boolean isNameEquals(String otherName) { final String thisName = getName().orElse("#"+otherName); return thisN"> getName() { return Optional.ofNullable(name); } private boolean isNameEquals(String otherName) { final String thisName = getName().orElse("#"+otherName); return thisN">
package br.edu.ifsp.lp3a5.refactoring.gildedrose;

import java.util.Optional;

class ItemUtil {
	final private static int QUALITY_MAX = 50;
	final private static int QUALITY_MIN = 0;
	
	protected static boolean isNotQualityMax(Item item) {
		return item.quality < QUALITY_MAX;
	}
	
	protected static boolean isNotQualityMin(Item item) {
		return item.quality > QUALITY_MIN;    		
	}
	
	protected static boolean hasType(Item item, ItemType argType) {
		ItemType typeFromName = ItemType.getTypeByName(item.name);
		return typeFromName.equals(argType);
	}
}

enum ItemType {
	AGED_BRIE("Aged Brie"),
	BACKSTAGE_PASSES("Backstage passes to a TAFKAL80ETC concert"),
	SULFURAS("Sulfuras, Hand of Ragnaros"),
	OTHERS(null);
	
	final private String name;
	
	ItemType(String name) {
		this.name = name;
	}
	
	public Optional<String> getName() {
		return Optional.ofNullable(name);
	}
	
	private boolean isNameEquals(String otherName) {
		final String thisName = getName().orElse("#"+otherName);
		return thisName.equals(otherName);
	}
	
	public static ItemType getTypeByName(String name) {
		ItemType retorno = null;
		for(  ItemType type : ItemType.values() ) {
			if ( type.isNameEquals(name) ) {
				retorno = type;
			}
		}
		return retorno == null? ItemType.OTHERS : retorno;
	}
}

class GildedRose {
	
    Item[] items;

    public GildedRose(Item[] items) {
        this.items = items;
    }
    

    public void updateQuality() {
        for (int i = 0; i < items.length; i++) {
            updateQualityByItem(items[i]);
        }
    }

	/**
	 * @param item
	 */
	private void updateQualityByItem(final Item item) {
		if (! ItemUtil.hasType(item, ItemType.AGED_BRIE)
		        && !ItemUtil.hasType(item, ItemType.BACKSTAGE_PASSES) ) {
		    if ( ItemUtil.isNotQualityMin(item) ) {
		        if (!ItemUtil.hasType(item, ItemType.SULFURAS)) {
		            item.quality = item.quality - 1;
		        }
		    }
		} else {
		    if ( ItemUtil.isNotQualityMax(item) ) {
		        item.quality = item.quality + 1;

		        if (ItemUtil.hasType(item, ItemType.BACKSTAGE_PASSES)) {
		            if (item.sellIn < 11) {
		                if ( ItemUtil.isNotQualityMax(item) ) {
		                    item.quality = item.quality + 1;
		                }
		            }

		            if (item.sellIn < 6) {
		                if ( ItemUtil.isNotQualityMax(item) ) {
		                    item.quality = item.quality + 1;
		                }
		            }
		        }
		    }
		}

		if (!ItemUtil.hasType(item, ItemType.SULFURAS)) {
		    item.sellIn = item.sellIn - 1;
		}

		if (item.sellIn < 0) {
		    if (!ItemUtil.hasType(item, ItemType.AGED_BRIE)) {
		        if (!ItemUtil.hasType(item, ItemType.BACKSTAGE_PASSES)) {
		            if ( ItemUtil.isNotQualityMin(item) ) {
		                if (!ItemUtil.hasType(item, ItemType.SULFURAS)) {
		                    item.quality = item.quality - 1;
		                }
		            }
		        } else {
		            item.quality = item.quality - item.quality;
		        }
		    } else {
		        if ( ItemUtil.isNotQualityMax(item) ) {
		            item.quality = item.quality + 1;
		        }
		    }
		}
	}
}
package br.edu.ifsp.lp3a5.refactoring.gildedrose;

public class Item {

    public String name;

    public int sellIn;

    public int quality;

    public Item(String name, int sellIn, int quality) {
        this.name = name;
        this.sellIn = sellIn;
        this.quality = quality;
    }

   @Override
   public String toString() {
        return this.name + ", " + this.sellIn + ", " + this.quality;
    }
}
package br.edu.ifsp.lp3a5.refactoring.gildedrose;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

class GildedRoseTest {
	
	final private static String SULFURAS = "Sulfuras, Hand of Ragnaros";
	final private static String BRIE = "Aged Brie"; 
	final private static String BACKSTAGE_PASSES = "Backstage passes to a TAFKAL80ETC concert";
	final private static String NORMAL_ITEM = "NORMAL ITEM";
	
	private Item createSulfuras() {
		return new Item(SULFURAS,-1,80);
	}
	
    void avancaDias(GildedRose app, int qtdDias) {
        for (int i = 0; i < qtdDias; i++) {
            app.updateQuality();
        }
    }

    @Test
    void testSulfuras() {
        Item[] items = new Item[] { createSulfuras() };
        GildedRose app = new GildedRose(items);
        app.updateQuality();
        assertEquals(SULFURAS, app.items[0].name);
        assertEquals(-1, app.items[0].sellIn);
        assertEquals(80, app.items[0].quality);
    }
    
    @Test
    void testNormalItem() {
    	Item[] items = new Item[] { new Item(NORMAL_ITEM, 1, 15) };
        GildedRose app = new GildedRose(items);
        app.updateQuality();
        assertEquals(NORMAL_ITEM, app.items[0].name);
        assertEquals(0, app.items[0].sellIn);
        assertEquals(14, app.items[0].quality);
        app.updateQuality();
        assertEquals(NORMAL_ITEM, app.items[0].name);
        assertEquals(-1, app.items[0].sellIn);
        assertEquals(12, app.items[0].quality);
    }
    
    @Test
    void testBrie() {
    	Item[] items = new Item[] { new Item(BRIE, 1, 48) };
        GildedRose app = new GildedRose(items);
        app.updateQuality();
        assertEquals(BRIE, app.items[0].name);
        assertEquals(0, app.items[0].sellIn);
        assertEquals(49, app.items[0].quality);
        app.updateQuality();
        assertEquals(BRIE, app.items[0].name);
        assertEquals(-1, app.items[0].sellIn);
        assertEquals(50, app.items[0].quality);
        app.updateQuality();
        assertEquals(BRIE, app.items[0].name);
        assertEquals(-2, app.items[0].sellIn);
        assertEquals(50, app.items[0].quality);
    }
    
    @Test
    void testPasses() {
    	Item[] items = new Item[] { new Item(BACKSTAGE_PASSES, 15, 30) };
        GildedRose app = new GildedRose(items);
        
        avancaDias(app, 1);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(14, app.items[0].sellIn);
        assertEquals(31, app.items[0].quality);
        
        avancaDias(app, 4);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(10, app.items[0].sellIn);
        assertEquals(35, app.items[0].quality);
        
        avancaDias(app, 1);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(9, app.items[0].sellIn);
        assertEquals(37, app.items[0].quality);
        
        avancaDias(app, 4);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(5, app.items[0].sellIn);
        assertEquals(45, app.items[0].quality);
        
        avancaDias(app, 1);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(4, app.items[0].sellIn);
        assertEquals(48, app.items[0].quality);
        
        avancaDias(app, 1);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(3, app.items[0].sellIn);
        assertEquals(50, app.items[0].quality);
        
        avancaDias(app, 3);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(0, app.items[0].sellIn);
        assertEquals(50, app.items[0].quality);
        
        avancaDias(app, 1);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(-1, app.items[0].sellIn);
        assertEquals(0, app.items[0].quality);
        
        avancaDias(app, 1);
        assertEquals(BACKSTAGE_PASSES, app.items[0].name);
        assertEquals(-2, app.items[0].sellIn);
        assertEquals(0, app.items[0].quality);
    }

}
package br.edu.ifsp.lp3a5.refactoring.gildedrose;

public class TexttestFixture {
    public static void main(String[] args) {
        System.out.println("OMGHAI!");

        Item[] items = new Item[] {
                new Item("+5 Dexterity Vest", 10, 20), //
                new Item("Aged Brie", 2, 0), //
                new Item("Elixir of the Mongoose", 5, 7), //
                new Item("Sulfuras, Hand of Ragnaros", 0, 80), //
                new Item("Sulfuras, Hand of Ragnaros", -1, 80),
                new Item("Backstage passes to a TAFKAL80ETC concert", 15, 20),
                new Item("Backstage passes to a TAFKAL80ETC concert", 10, 49),
                new Item("Backstage passes to a TAFKAL80ETC concert", 5, 49),
                // this conjured item does not work properly yet
                new Item("Conjured Mana Cake", 3, 6) };

        GildedRose app = new GildedRose(items);

        int days = 2;
        if (args.length > 0) {
            days = Integer.parseInt(args[0]) + 1;
        }

        for (int i = 0; i < days; i++) {
            System.out.println("-------- day " + i + " --------");
            System.out.println("name, sellIn, quality");
            for (Item item : items) {
                System.out.println(item);
            }
            System.out.println();
            app.updateQuality();
        }
    }

}