001/*
002 * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
003 * Copyright (C) 2000-2011 The Gridarta Developers.
004 *
005 * This program is free software; you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation; either version 2 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License along
016 * with this program; if not, write to the Free Software Foundation, Inc.,
017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
018 */
019
020package net.sf.gridarta.model.mapmodel;
021
022import java.util.Arrays;
023import java.util.Collection;
024import java.util.HashSet;
025import java.util.Iterator;
026import java.util.NoSuchElementException;
027import net.sf.gridarta.model.archetype.TestArchetype;
028import net.sf.gridarta.model.gameobject.GameObject;
029import net.sf.gridarta.model.gameobject.TestGameObject;
030import net.sf.gridarta.model.maparchobject.TestMapArchObject;
031import net.sf.gridarta.model.match.GameObjectMatcher;
032import org.jetbrains.annotations.NotNull;
033import org.junit.Assert;
034import org.junit.Test;
035
036/**
037 * Regression tests for {@link FilterGameObjectIterator}.
038 * @author Andreas Kirschbaum
039 */
040public class FilterGameObjectIteratorTest {
041
042    /**
043     * Checks that an empty iterator is filtered correctly.
044     */
045    @Test
046    public void testEmptyIterator() {
047        check(new AcceptAllMatcher(), new ArrayGameObjectIterator());
048    }
049
050    /**
051     * Checks that a matcher that accepts all game objects returns all game
052     * objects.
053     */
054    @Test
055    public void testAllMatcher() {
056        final TestMapModelCreator creator = new TestMapModelCreator(false);
057        final TestGameObject o1 = creator.newGameObject("arch", "o1");
058        final TestGameObject o2 = creator.newGameObject("arch", "o2");
059        final TestGameObject o3 = creator.newGameObject("arch", "o3");
060        check(new AcceptAllMatcher(), new ArrayGameObjectIterator(o1, o2, o3), o1, o2, o3);
061    }
062
063    /**
064     * Checks that a matcher that accepts some game objects returns only the
065     * accepted game objects.
066     */
067    @Test
068    public void testAcceptMatcher() {
069        final TestMapModelCreator creator = new TestMapModelCreator(false);
070        final TestGameObject o1 = creator.newGameObject("arch", "o1");
071        final TestGameObject o2 = creator.newGameObject("arch", "o2");
072        final TestGameObject o3 = creator.newGameObject("arch", "o3");
073        check(new AcceptMatcher(o1, o2), new ArrayGameObjectIterator(o1, o2, o3, o1, o2, o3, o1, o1, o2, o3, o3), o1, o2, o1, o2, o1, o1, o2);
074    }
075
076    /**
077     * Creates a new {@link FilterGameObjectIterator} instance and checks that
078     * it returns the expected game objects.
079     * @param matcher the matcher for the filter game object iterator
080     * @param iterator the underlying iterator for the filter game object
081     * iterator
082     * @param gameObjects the expected game objects to be returned from the
083     * filter game object iterator
084     */
085    private static void check(@NotNull final GameObjectMatcher matcher, @NotNull final Iterator<TestGameObject> iterator, @NotNull final TestGameObject... gameObjects) {
086        final Iterator<TestGameObject> filterGameObjectIterator = new FilterGameObjectIterator<TestGameObject, TestMapArchObject, TestArchetype>(iterator, matcher);
087        for (final TestGameObject gameObject : gameObjects) {
088            Assert.assertTrue(filterGameObjectIterator.hasNext());
089            Assert.assertSame(gameObject, filterGameObjectIterator.next());
090        }
091        Assert.assertFalse(filterGameObjectIterator.hasNext());
092    }
093
094    /**
095     * A {@link GameObjectMatcher} that accepts all game objects.
096     */
097    private static class AcceptAllMatcher implements GameObjectMatcher {
098
099        /**
100         * The serial version UID.
101         */
102        private static final long serialVersionUID = 1L;
103
104        @Override
105        public boolean isMatching(@NotNull final GameObject<?, ?, ?> gameObject) {
106            return true;
107        }
108
109    }
110
111    /**
112     * A {@link GameObjectMatcher} that accepts a set of game objects.
113     */
114    private static class AcceptMatcher implements GameObjectMatcher {
115
116        /**
117         * The serial version UID.
118         */
119        private static final long serialVersionUID = 1L;
120
121        /**
122         * The accepted game objects.
123         */
124        @NotNull
125        private final Collection<GameObject<?, ?, ?>> gameObjects = new HashSet<GameObject<?, ?, ?>>();
126
127        /**
128         * Creates a new instance.
129         * @param gameObjects the game objects to accept
130         */
131        private AcceptMatcher(@NotNull final GameObject<?, ?, ?>... gameObjects) {
132            this.gameObjects.addAll(Arrays.asList(gameObjects));
133        }
134
135        @Override
136        public boolean isMatching(@NotNull final GameObject<?, ?, ?> gameObject) {
137            return gameObjects.contains(gameObject);
138        }
139
140    }
141
142    /**
143     * An {@link Iterator} that returns a fixed list of {@link GameObject
144     * GameObjects}.
145     */
146    private static class ArrayGameObjectIterator implements Iterator<TestGameObject> {
147
148        /**
149         * The {@link GameObject GameObjects} to return.
150         */
151        @NotNull
152        private final TestGameObject[] gameObjects;
153
154        /**
155         * The current index into {@link #gameObjects}.
156         */
157        private int index;
158
159        /**
160         * Creates a new instance.
161         * @param gameObjects the game objects to return
162         */
163        private ArrayGameObjectIterator(@NotNull final TestGameObject... gameObjects) {
164            this.gameObjects = gameObjects.clone();
165        }
166
167        @Override
168        public boolean hasNext() {
169            return index < gameObjects.length;
170        }
171
172        @Override
173        public TestGameObject next() {
174            if (index >= gameObjects.length) {
175                throw new NoSuchElementException();
176            }
177            return gameObjects[index++];
178        }
179
180        @Override
181        public void remove() {
182            throw new UnsupportedOperationException();
183        }
184
185    }
186
187}