From 3148dd706348f21b0f2ea746b41c249991c1e20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20D=C3=ADaz?= Date: Sat, 8 Oct 2016 16:05:18 -0400 Subject: [PATCH] Rename NICK with truncation. Code is tested --- .../module/feature/rename/RenameFormat.java | 103 +++++++++++++ .../feature/rename/RenamePreferences.java | 4 + .../feature/rename/RenameFormatTest.java | 141 ++++++++++++++++++ buildscript/dependencies.gradle | 2 +- 4 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/icecream/snorlax/module/feature/rename/RenameFormat.java create mode 100644 app/src/test/java/com/icecream/snorlax/module/feature/rename/RenameFormatTest.java diff --git a/app/src/main/java/com/icecream/snorlax/module/feature/rename/RenameFormat.java b/app/src/main/java/com/icecream/snorlax/module/feature/rename/RenameFormat.java new file mode 100644 index 0000000..b5d567f --- /dev/null +++ b/app/src/main/java/com/icecream/snorlax/module/feature/rename/RenameFormat.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016. Pedro Diaz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.icecream.snorlax.module.feature.rename; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import android.support.annotation.Nullable; + +import com.icecream.snorlax.common.Strings; +import com.icecream.snorlax.module.Pokemons; + +import static POGOProtos.Data.PokemonDataOuterClass.PokemonData; + +@Singleton +final class RenameFormat { + + private static final String BASE_NICK = "NICK"; + + private final Pokemons mPokemons; + private final RenamePreferences mRenamePreferences; + + @Inject + RenameFormat(Pokemons pokemons, RenamePreferences renamePreferences) { + mPokemons = pokemons; + mRenamePreferences = renamePreferences; + } + + @Nullable + private String processNick(String target, String nick) { + final int length = target.length(); + final int dot = target.indexOf('.') + 1; + + if (length == BASE_NICK.length()) { + return nick; + } + else if (dot > 0 && length > dot) { + try { + return Strings.truncateAt(nick, Integer.parseInt(target.substring(dot))); + } + catch (NumberFormatException ignored) { + } + } + return null; + } + + private String processFormat(Pokemons.Data pokemonsData, String command) throws NullPointerException { + final String target = command.toUpperCase(); + + String processed = null; + + if (target.startsWith(BASE_NICK)) { + processed = processNick(target, pokemonsData.getName()); + } + + return Strings.isNullOrEmpty(processed) ? "%" + command + "%" : processed; + } + + String format(PokemonData pokemonData) throws NullPointerException, IllegalArgumentException { + final Pokemons.Data data = mPokemons.with(pokemonData); + final String format = mRenamePreferences.getFormat(); + + StringBuilder builder = new StringBuilder(); + + for (int i = 0, len = format.length(); i < len; ) { + int nextPercent = format.indexOf('%', i + 1); + if (format.charAt(i) != '%') { + final int end = (nextPercent == -1) ? len : nextPercent; + + builder.append(format.substring(i, end)); + i = end; + } + else if (nextPercent == -1) { + builder.append(format.substring(i)); + i = len; + } + else if (format.substring(i + 1, nextPercent).contains(" ")) { + builder.append(format.substring(i, nextPercent)); + i = nextPercent; + } + else { + builder.append(processFormat(data, format.substring(i + 1, nextPercent))); + i = nextPercent + 1; + } + } + + return builder.toString(); + } +} diff --git a/app/src/main/java/com/icecream/snorlax/module/feature/rename/RenamePreferences.java b/app/src/main/java/com/icecream/snorlax/module/feature/rename/RenamePreferences.java index 2e9cb97..8bd62d2 100644 --- a/app/src/main/java/com/icecream/snorlax/module/feature/rename/RenamePreferences.java +++ b/app/src/main/java/com/icecream/snorlax/module/feature/rename/RenamePreferences.java @@ -38,6 +38,10 @@ final class RenamePreferences { mPreferences = preferences; } + String getFormat() { + throw new RuntimeException("Not implemented"); + } + boolean isEnabled() { mPreferences.reload(); final boolean expected = getPreferenceDefaultValue(); diff --git a/app/src/test/java/com/icecream/snorlax/module/feature/rename/RenameFormatTest.java b/app/src/test/java/com/icecream/snorlax/module/feature/rename/RenameFormatTest.java new file mode 100644 index 0000000..1f56cd8 --- /dev/null +++ b/app/src/test/java/com/icecream/snorlax/module/feature/rename/RenameFormatTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016. Pedro Diaz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.icecream.snorlax.module.feature.rename; + +import com.icecream.snorlax.module.Pokemons; + +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static POGOProtos.Data.PokemonDataOuterClass.PokemonData; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ + Pokemons.class, + PokemonData.class, + RenamePreferences.class +}) +public class RenameFormatTest { + + private static final String POKEMON_NAME = "Snorlax"; + private static final float POKEMON_LEVEL = 22.5f; + + @Mock + private Pokemons mPokemons; + @Mock + private Pokemons.Data mPokemonsData; + @Mock + private RenamePreferences mRenamePreferences; + @Mock + private PokemonData mProto; + + @InjectMocks + private RenameFormat mSut; + + private String mExpected; + + private void setRenameFormat(String format) { + Mockito + .doReturn(format) + .when(mRenamePreferences) + .getFormat(); + } + + @Before + public void setUp() throws Exception { + // Given + Mockito.doReturn(mPokemonsData).when(mPokemons).with(mProto); + Mockito.doReturn(POKEMON_NAME).when(mPokemonsData).getName(); + Mockito.doReturn(POKEMON_LEVEL).when(mPokemonsData).getLevel(); + } + + @After + public void tearDown() throws Exception { + // When + final String formatted = mSut.format(mProto); + + // Then + Mockito.verify(mPokemons).with(mProto); + Mockito.verify(mRenamePreferences).getFormat(); + Mockito.verifyNoMoreInteractions(mPokemons, mRenamePreferences); + + MatcherAssert.assertThat(formatted, Matchers.is(mExpected)); + } + + @Test + public void testNicknameCompleteFormat() throws Exception { + mExpected = POKEMON_NAME; + setRenameFormat("%NICK%"); + } + + @Test + public void testNicknameIncompleteFormat() throws Exception { + mExpected = "%NICK"; + setRenameFormat("%NICK"); + } + + @Test + public void testNicknameTruncateBelowLength() throws Exception { + mExpected = POKEMON_NAME.substring(0, 3); + setRenameFormat("%NICK.3%"); + } + + @Test + public void testNicknameTruncateExactLength() throws Exception { + mExpected = POKEMON_NAME; + setRenameFormat("%NICK.7%"); + } + + @Test + public void testNicknameTruncateAboveLength() throws Exception { + mExpected= POKEMON_NAME; + setRenameFormat("%NICK.30%"); + } + + @Test + public void testNicknameTruncateIncompleteFormat() throws Exception { + mExpected = "%NICK.%"; + setRenameFormat("%NICK.%"); + } + + @Test + public void testNicknameTruncateWrongFormat() throws Exception { + mExpected = "%NICK.1a%"; + setRenameFormat("%NICK.1a%"); + } + + @Test + public void testNicknameFormatWithPlainText() throws Exception { + setRenameFormat("Plain Text %NICK%"); + mExpected = "Plain Text " + POKEMON_NAME; + } + + @Test + public void testNicknameFormatWithSpaces() throws Exception { + setRenameFormat("%NICK %NICK%"); + mExpected = "%NICK " + POKEMON_NAME; + } +} \ No newline at end of file diff --git a/buildscript/dependencies.gradle b/buildscript/dependencies.gradle index f120940..07cb27e 100644 --- a/buildscript/dependencies.gradle +++ b/buildscript/dependencies.gradle @@ -7,7 +7,7 @@ ext { ] testVersions = [ junit : '4.12', - mockito : '2.1.0', + mockito : '2.0.0-beta', hamcrest : '1.4-atlassian-1', powermock: '1.6.5' ]