package com.basgeekball.awesomevalidation.validators; import android.app.Activity; import android.support.design.widget.TextInputLayout; import android.text.SpannableStringBuilder; import android.widget.EditText; import com.basgeekball.awesomevalidation.ValidationHolder; import com.basgeekball.awesomevalidation.model.NumericRange; import com.basgeekball.awesomevalidation.utility.ValidationCallback; import junit.framework.TestCase; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.api.mockito.expectation.PowerMockitoStubber; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.basgeekball.awesomevalidation.validators.MockValidationHolderHelper.ValidationHolderType.CONFIRMATION; import static com.basgeekball.awesomevalidation.validators.MockValidationHolderHelper.ValidationHolderType.RANGE; import static com.basgeekball.awesomevalidation.validators.MockValidationHolderHelper.ValidationHolderType.REGEX; import static com.basgeekball.awesomevalidation.validators.MockValidationHolderHelper.generate; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.verifyPrivate; @RunWith(PowerMockRunner.class) @PrepareForTest({Validator.class, Pattern.class}) public class ValidatorTest extends TestCase { private Validator mSpiedValidator = PowerMockito.spy(new Validator() { @Override public boolean trigger() { return false; } @Override public void halt() { // intentionally empty, no need to test here } }); private ValidationCallback mEmptyValidationCallback = new ValidationCallback() { @Override public void execute(ValidationHolder validationHolder, Matcher matcher) { // intentionally empty, no need to test here } }; private void mockPrivateMethods() { try { PowerMockito.doNothing().when(mSpiedValidator, "executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); PowerMockito.doNothing().when(mSpiedValidator, "requestFocus", any(ValidationHolder.class)); } catch (Exception e) { e.printStackTrace(); } } private void mockCheckSomeCertainTypeField(String methodName, List<Boolean> returnValues) { try { PowerMockitoStubber stubber = PowerMockito.doReturn(returnValues.get(0)); for (int i = 1; i < returnValues.size(); i++) { stubber = (PowerMockitoStubber) stubber.doReturn(returnValues.get(i)); } stubber.when(mSpiedValidator, methodName, any(ValidationHolder.class), any(ValidationCallback.class)); } catch (Exception e) { e.printStackTrace(); } } private void mockCheckRegexTypeField(List<Boolean> returnValues) { mockCheckSomeCertainTypeField("checkRegexTypeField", returnValues); } private void mockCheckRangeTypeField(List<Boolean> returnValues) { mockCheckSomeCertainTypeField("checkRangeTypeField", returnValues); } private void mockCheckConfirmationTypeField(List<Boolean> returnValues) { mockCheckSomeCertainTypeField("checkConfirmationTypeField", returnValues); } private void mockCheckRegexTypeField(boolean returnValue) { mockCheckRegexTypeField(Arrays.asList(returnValue)); } private void mockCheckRangeTypeField(boolean returnValue) { mockCheckRangeTypeField(Arrays.asList(returnValue)); } private void mockCheckConfirmationTypeField(boolean returnValue) { mockCheckConfirmationTypeField(Arrays.asList(returnValue)); } public void testValidator() { assertTrue(mSpiedValidator.mValidationHolderList.isEmpty()); } public void testSetEditTextWithActivityAndRegex() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int viewId = 1; String regex = "OK"; int errMsgId = 9; String errMsg = "Error"; EditText mockEditText = mock(EditText.class); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockEditText); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, viewId, regex, errMsgId); verify(mSpiedValidator, times(1)).set(mockEditText, regex, errMsg); } public void testSetTextInputLayoutWithActivityAndRegex() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int viewId = 1; String regex = "OK"; int errMsgId = 9; String errMsg = "Error"; TextInputLayout mockTextInputLayout = mock(TextInputLayout.class); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockTextInputLayout); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, viewId, regex, errMsgId); verify(mSpiedValidator, times(1)).set(mockTextInputLayout, regex, errMsg); } public void testSetEditTextWithActivityAndPattern() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int viewId = 1; Pattern mockPattern = PowerMockito.mock(Pattern.class); int errMsgId = 9; String errMsg = "Error"; EditText mockEditText = mock(EditText.class); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockEditText); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, viewId, mockPattern, errMsgId); verify(mSpiedValidator, times(1)).set(mockEditText, mockPattern, errMsg); } public void testSetTextInputLayoutWithActivityAndPattern() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int viewId = 1; Pattern mockPattern = PowerMockito.mock(Pattern.class); int errMsgId = 9; String errMsg = "Error"; TextInputLayout mockTextInputLayout = mock(TextInputLayout.class); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockTextInputLayout); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, viewId, mockPattern, errMsgId); verify(mSpiedValidator, times(1)).set(mockTextInputLayout, mockPattern, errMsg); } public void testSetEditTextWithActivityAndNumericRange() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int viewId = 1; NumericRange mockNumericRange = mock(NumericRange.class); int errMsgId = 9; String errMsg = "Error"; EditText mockEditText = mock(EditText.class); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockEditText); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, viewId, mockNumericRange, errMsgId); verify(mSpiedValidator, times(1)).set(mockEditText, mockNumericRange, errMsg); } public void testSetTextInputLayoutWithActivityAndNumericRange() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int viewId = 1; NumericRange mockNumericRange = mock(NumericRange.class); int errMsgId = 9; String errMsg = "Error"; TextInputLayout mockTextInputLayout = mock(TextInputLayout.class); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockTextInputLayout); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, viewId, mockNumericRange, errMsgId); verify(mSpiedValidator, times(1)).set(mockTextInputLayout, mockNumericRange, errMsg); } public void testSetEditTextWithActivityAndConfirmation() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int confirmationViewId = 0; int viewId = 1; int errMsgId = 9; String errMsg = "Error"; EditText mockConfirmationEditText = mock(EditText.class); EditText mockEditText = mock(EditText.class); when(mockActivity.findViewById(eq(confirmationViewId))).thenReturn(mockConfirmationEditText); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockEditText); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, confirmationViewId, viewId, errMsgId); verify(mSpiedValidator, times(1)).set(mockConfirmationEditText, mockEditText, errMsg); } public void testSetTextInputLayoutWithActivityAndConfirmation() { Activity mockActivity = mock(Activity.class, RETURNS_DEEP_STUBS); int confirmationViewId = 0; int viewId = 1; int errMsgId = 9; String errMsg = "Error"; TextInputLayout mockConfirmationTextInputLayout = mock(TextInputLayout.class); TextInputLayout mockTextInputLayout = mock(TextInputLayout.class); when(mockActivity.findViewById(eq(confirmationViewId))).thenReturn(mockConfirmationTextInputLayout); when(mockActivity.findViewById(eq(viewId))).thenReturn(mockTextInputLayout); when(mockActivity.getResources().getString(eq(errMsgId))).thenReturn(errMsg); mSpiedValidator.set(mockActivity, confirmationViewId, viewId, errMsgId); verify(mSpiedValidator, times(1)).set(mockConfirmationTextInputLayout, mockTextInputLayout, errMsg); } public void testCheckFieldsPassWithOnlyOneRegexValidationHolder() { mockPrivateMethods(); mockCheckRegexTypeField(true); mSpiedValidator.mValidationHolderList.add(generate(REGEX)); assertTrue(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsFailWithOnlyOneRegexValidationHolder() { mockPrivateMethods(); mockCheckRegexTypeField(false); mSpiedValidator.mValidationHolderList.add(generate(REGEX)); assertFalse(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsPassWithOnlyOneRangeValidationHolder() { mockPrivateMethods(); mockCheckRangeTypeField(true); mSpiedValidator.mValidationHolderList.add(generate(RANGE)); assertTrue(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsFailWithOnlyOneRangeValidationHolder() { mockPrivateMethods(); mockCheckRangeTypeField(false); mSpiedValidator.mValidationHolderList.add(generate(RANGE)); assertFalse(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsPassWithOnlyOneConfirmationValidationHolder() { mockPrivateMethods(); mockCheckConfirmationTypeField(true); mSpiedValidator.mValidationHolderList.add(generate(CONFIRMATION)); assertTrue(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsFailWithOnlyOneConfirmationValidationHolder() { mockPrivateMethods(); mockCheckConfirmationTypeField(false); mSpiedValidator.mValidationHolderList.add(generate(CONFIRMATION)); assertFalse(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsPassWithManyDifferentValidationHolders() { mockPrivateMethods(); mockCheckRegexTypeField(Arrays.asList(true, true)); mockCheckRangeTypeField(Arrays.asList(true, true)); mockCheckConfirmationTypeField(Arrays.asList(true, true)); mSpiedValidator.mValidationHolderList.addAll(Arrays.asList( generate(REGEX), generate(RANGE), generate(CONFIRMATION), generate(REGEX), generate(RANGE), generate(CONFIRMATION) )); assertTrue(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsFailDueToOneRegexFromManyDifferentValidationHolders() { mockPrivateMethods(); mockCheckRegexTypeField(Arrays.asList(true, false, true)); mockCheckRangeTypeField(Arrays.asList(true, true, true)); mockCheckConfirmationTypeField(Arrays.asList(true, true, true)); mSpiedValidator.mValidationHolderList.addAll(Arrays.asList( generate(REGEX), generate(RANGE), generate(CONFIRMATION), generate(REGEX), generate(RANGE), generate(CONFIRMATION), generate(REGEX), generate(RANGE), generate(CONFIRMATION) )); assertFalse(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsFailDueToOneRangeFromManyDifferentValidationHolders() { mockPrivateMethods(); mockCheckRegexTypeField(Arrays.asList(true, true, true)); mockCheckRangeTypeField(Arrays.asList(true, false, true)); mockCheckConfirmationTypeField(Arrays.asList(true, true, true)); mSpiedValidator.mValidationHolderList.addAll(Arrays.asList( generate(REGEX), generate(RANGE), generate(CONFIRMATION), generate(REGEX), generate(RANGE), generate(CONFIRMATION), generate(REGEX), generate(RANGE), generate(CONFIRMATION) )); assertFalse(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckFieldsFailDueToOneConfirmationFromManyDifferentValidationHolders() { mockPrivateMethods(); mockCheckRegexTypeField(Arrays.asList(true, true, true)); mockCheckRangeTypeField(Arrays.asList(true, true, true)); mockCheckConfirmationTypeField(Arrays.asList(true, false, true)); mSpiedValidator.mValidationHolderList.addAll(Arrays.asList( generate(REGEX), generate(RANGE), generate(CONFIRMATION), generate(REGEX), generate(RANGE), generate(CONFIRMATION), generate(REGEX), generate(RANGE), generate(CONFIRMATION) )); assertFalse(mSpiedValidator.checkFields(mEmptyValidationCallback)); } public void testCheckRegexTypeFieldPass() throws Exception { ValidationHolder mockValidationHolder = generate(REGEX); Pattern mockPattern = PowerMockito.mock(Pattern.class); String mockString = PowerMockito.mock(String.class); Matcher mockMatcher = PowerMockito.mock(Matcher.class); when(mockValidationHolder.getPattern()).thenReturn(mockPattern); when(mockValidationHolder.getText()).thenReturn(mockString); when(mockPattern.matcher(mockString)).thenReturn(mockMatcher); when(mockMatcher.matches()).thenReturn(true); assertTrue((Boolean) Whitebox.invokeMethod(mSpiedValidator, "checkRegexTypeField", mockValidationHolder, mEmptyValidationCallback)); verifyPrivate(mSpiedValidator, never()).invoke("executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); } public void testCheckRegexTypeFieldFail() throws Exception { ValidationHolder mockValidationHolder = generate(REGEX); Pattern mockPattern = PowerMockito.mock(Pattern.class); String mockString = PowerMockito.mock(String.class); Matcher mockMatcher = PowerMockito.mock(Matcher.class); when(mockValidationHolder.getPattern()).thenReturn(mockPattern); when(mockValidationHolder.getText()).thenReturn(mockString); when(mockPattern.matcher(mockString)).thenReturn(mockMatcher); when(mockMatcher.matches()).thenReturn(false); PowerMockito.doNothing().when(mSpiedValidator, "executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); assertFalse((Boolean) Whitebox.invokeMethod(mSpiedValidator, "checkRegexTypeField", mockValidationHolder, mEmptyValidationCallback)); verifyPrivate(mSpiedValidator, times(1)).invoke("executeCallback", mEmptyValidationCallback, mockValidationHolder, mockMatcher); } public void testCheckRangeTypeFieldPass() throws Exception { ValidationHolder mockValidationHolder = generate(RANGE); NumericRange mockNumericRange = mock(NumericRange.class); String mockString = PowerMockito.mock(String.class); when(mockValidationHolder.getText()).thenReturn(mockString); when(mockValidationHolder.getNumericRange()).thenReturn(mockNumericRange); when(mockNumericRange.isValid(mockString)).thenReturn(true); assertTrue((Boolean) Whitebox.invokeMethod(mSpiedValidator, "checkRangeTypeField", mockValidationHolder, mEmptyValidationCallback)); verifyPrivate(mSpiedValidator, never()).invoke("executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); } public void testCheckRangeTypeFieldFail() throws Exception { ValidationHolder mockValidationHolder = generate(RANGE); NumericRange mockNumericRange = mock(NumericRange.class); String mockString = PowerMockito.mock(String.class); when(mockValidationHolder.getText()).thenReturn(mockString); when(mockValidationHolder.getNumericRange()).thenReturn(mockNumericRange); when(mockNumericRange.isValid(mockString)).thenReturn(false); PowerMockito.mockStatic(Pattern.class); Pattern mockPattern = PowerMockito.mock(Pattern.class); Matcher mockMatcher = PowerMockito.mock(Matcher.class); when(Pattern.compile(anyString())).thenReturn(mockPattern); when(mockPattern.matcher(mockString)).thenReturn(mockMatcher); PowerMockito.doNothing().when(mSpiedValidator, "executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); assertFalse((Boolean) Whitebox.invokeMethod(mSpiedValidator, "checkRangeTypeField", mockValidationHolder, mEmptyValidationCallback)); verifyPrivate(mSpiedValidator, times(1)).invoke("executeCallback", mEmptyValidationCallback, mockValidationHolder, mockMatcher); } public void testCheckRangeTypeFieldFailDueToException() throws Exception { ValidationHolder mockValidationHolder = generate(RANGE); NumericRange mockNumericRange = mock(NumericRange.class); String mockString = PowerMockito.mock(String.class); when(mockValidationHolder.getText()).thenReturn(mockString); when(mockValidationHolder.getNumericRange()).thenReturn(mockNumericRange); doThrow(NumberFormatException.class).when(mockNumericRange).isValid(mockString); PowerMockito.mockStatic(Pattern.class); Pattern mockPattern = PowerMockito.mock(Pattern.class); Matcher mockMatcher = PowerMockito.mock(Matcher.class); when(Pattern.compile(anyString())).thenReturn(mockPattern); when(mockPattern.matcher(mockString)).thenReturn(mockMatcher); PowerMockito.doNothing().when(mSpiedValidator, "executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); assertFalse((Boolean) Whitebox.invokeMethod(mSpiedValidator, "checkRangeTypeField", mockValidationHolder, mEmptyValidationCallback)); verifyPrivate(mSpiedValidator, times(1)).invoke("executeCallback", mEmptyValidationCallback, mockValidationHolder, mockMatcher); } public void testCheckConfirmationTypeFieldPass() throws Exception { ValidationHolder mockValidationHolder = generate(CONFIRMATION); String mockStringA = "aaa"; String mockStringB = "aaa"; when(mockValidationHolder.getText()).thenReturn(mockStringA); when(mockValidationHolder.getConfirmationText()).thenReturn(mockStringB); assertTrue((Boolean) Whitebox.invokeMethod(mSpiedValidator, "checkConfirmationTypeField", mockValidationHolder, mEmptyValidationCallback)); verifyPrivate(mSpiedValidator, never()).invoke("executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); } public void testCheckConfirmationTypeFieldFail() throws Exception { ValidationHolder mockValidationHolder = generate(CONFIRMATION); String mockStringA = "aaa"; String mockStringB = "bbb"; when(mockValidationHolder.getText()).thenReturn(mockStringA); when(mockValidationHolder.getConfirmationText()).thenReturn(mockStringB); PowerMockito.doNothing().when(mSpiedValidator, "executeCallback", any(ValidationCallback.class), any(ValidationHolder.class), any(Matcher.class)); assertFalse((Boolean) Whitebox.invokeMethod(mSpiedValidator, "checkConfirmationTypeField", mockValidationHolder, mEmptyValidationCallback)); verifyPrivate(mSpiedValidator, times(1)).invoke("executeCallback", mEmptyValidationCallback, mockValidationHolder, null); } public void testExecuteCallback() throws Exception { ValidationHolder mockValidationHolder = mock(ValidationHolder.class); ValidationCallback mockValidationCallback = mock(ValidationCallback.class); Matcher mockMatcher = PowerMockito.mock(Matcher.class); doNothing().when(mockValidationCallback).execute(any(ValidationHolder.class), any(Matcher.class)); PowerMockito.doNothing().when(mSpiedValidator, "requestFocus", any(ValidationHolder.class)); Whitebox.invokeMethod(mSpiedValidator, "executeCallback", mockValidationCallback, mockValidationHolder, mockMatcher); verify(mockValidationCallback).execute(mockValidationHolder, mockMatcher); verifyPrivate(mSpiedValidator, times(1)).invoke("requestFocus", mockValidationHolder); } public void testRequestFocus() throws Exception { ValidationHolder mockValidationHolder = mock(ValidationHolder.class); EditText mockEditText = mock(EditText.class); SpannableStringBuilder mockEditable = PowerMockito.mock(SpannableStringBuilder.class); when(mockValidationHolder.getEditText()).thenReturn(mockEditText); when(mockEditText.getText()).thenReturn(mockEditable); when(mockEditable.length()).thenReturn(PowerMockito.mock(Integer.class)); when(mockEditText.requestFocus()).thenReturn(true); doNothing().when(mockEditText).setSelection(anyInt()); Whitebox.setInternalState(mSpiedValidator, "mHasFailed", false); Whitebox.invokeMethod(mSpiedValidator, "requestFocus", mockValidationHolder); assertTrue((Boolean) Whitebox.getInternalState(mSpiedValidator, "mHasFailed")); } }