From 6540485a37e4af7294909c65ebea1b13ac3b3602 Mon Sep 17 00:00:00 2001 From: Julian Date: Fri, 6 Sep 2019 14:03:53 -0400 Subject: [PATCH 1/4] migrate java files to kotlin --- build.gradle | 23 +- gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- sample/build.gradle | 29 ++- .../MainActivity.java | 120 --------- .../MainActivity.kt | 81 ++++++ sample/src/main/res/layout/activity_main.xml | 12 +- sample/src/main/res/layout/content_main.xml | 16 +- validatedtextinputlayout/build.gradle | 19 +- .../ValidatedTextInputLayout.java | 246 ------------------ .../ValidatedTextInputLayout.kt | 230 ++++++++++++++++ .../validator/BaseValidator.java | 82 ------ .../validator/BaseValidator.kt | 38 +++ .../validator/DependencyValidator.java | 78 ------ .../validator/DependencyValidator.kt | 49 ++++ .../validator/IValidator.java | 10 - .../validator/LengthValidator.java | 132 ---------- .../validator/LengthValidator.kt | 49 ++++ .../validator/RegexValidator.java | 47 ---- .../validator/RegexValidator.kt | 29 +++ .../validator/RequiredValidator.java | 38 --- .../validator/RequiredValidator.kt | 25 ++ .../validator/ValidationCallback.java | 9 - .../BaseValidatorTest.java | 2 +- .../LengthValidatorTest.java | 4 +- 25 files changed, 572 insertions(+), 802 deletions(-) delete mode 100644 sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.java create mode 100644 sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.java create mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.kt delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.java create mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.java create mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/IValidator.java delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.java create mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.java create mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.java create mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt delete mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.java diff --git a/build.gradle b/build.gradle index 211a0ab..d35ec2f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,17 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.3' + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -16,13 +21,23 @@ buildscript { allprojects { repositories { jcenter() + google() } } -task clean(type: Delete) { +tasks.register("clean") { delete rootProject.buildDir } -task runUnitTests(dependsOn: [':validatedtextinputlayout:test']) { +tasks.register("runUnitTests") { + dependsOn 'validatedtextinputlayout:test' description 'Run unit tests for the validatedtextinputlayout.' } + +//task clean(type: Delete) { +// delete rootProject.buildDir +//} +// +//task runUnitTests(dependsOn: [':validatedtextinputlayout:test']) { +// description 'Run unit tests for the validatedtextinputlayout.' +//} diff --git a/gradle.properties b/gradle.properties index 1d3591c..59d5aab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,6 @@ # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fcefeaf..98676f7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/sample/build.gradle b/sample/build.gradle index 5d5a3ea..73b097d 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,16 +1,23 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + compileSdkVersion 29 defaultConfig { applicationId "com.julianraj.validatedtextinputlayout" - minSdkVersion 9 - targetSdkVersion 25 + minSdkVersion 19 + targetSdkVersion 29 versionCode 2 versionName "1.0" } + + compileOptions { + targetCompatibility 1.8 + sourceCompatibility 1.8 + } + buildTypes { release { minifyEnabled false @@ -20,10 +27,14 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' + implementation fileTree(dir: 'libs', include: ['*.jar']) + testImplementation 'junit:junit:4.12' + + implementation project(':validatedtextinputlayout') + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'com.google.android.material:material:1.0.0' +} - compile project(':validatedtextinputlayout') - compile 'com.android.support:appcompat-v7:25.3.1' - compile 'com.android.support:design:25.3.1' +repositories { + mavenCentral() } diff --git a/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.java b/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.java deleted file mode 100644 index cc9c58d..0000000 --- a/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.julianraj.validatedtextinputlayoutsample; - -import android.os.Bundle; -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.Snackbar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Toast; - -import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout; -import com.julianraj.validatedtextinputlayout.validator.BaseValidator; -import com.julianraj.validatedtextinputlayout.validator.DependencyValidator; -import com.julianraj.validatedtextinputlayout.validator.ValidationCallback; - -public class MainActivity extends AppCompatActivity { - - FloatingActionButton fab; - ValidatedTextInputLayout mUsernameInput; - ValidatedTextInputLayout mPasswordInput; - ValidatedTextInputLayout mConfPasswordInput; - ValidatedTextInputLayout mEmailInput; - ValidatedTextInputLayout mCustomInput; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - - fab = (FloatingActionButton) findViewById(R.id.fab); - fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - submitForm(); - } - }); - - mUsernameInput = ((ValidatedTextInputLayout) findViewById(R.id.username)); - - mPasswordInput = ((ValidatedTextInputLayout) findViewById(R.id.password)); - mPasswordInput.setCounterEnabled(true); - - mConfPasswordInput = ((ValidatedTextInputLayout) findViewById(R.id.conf_password)); - mConfPasswordInput.addValidator(new DependencyValidator(mPasswordInput, - DependencyValidator.TYPE_EQUAL, "Confirmation password does not match the " + - "password.")); - - mEmailInput = ((ValidatedTextInputLayout) findViewById(R.id.email)); - - mCustomInput = ((ValidatedTextInputLayout) findViewById(R.id.custom)); - ValidationCallback mCallback = new ValidationCallback() { - @Override - public void onValidation(boolean status) { - if (!status) - Toast.makeText(MainActivity.this, "Your validation callback was called.", - Toast.LENGTH_SHORT).show(); - } - }; - mCustomInput.addValidator(new BaseValidator("Only accepts the word 'Valid'", mCallback) { - @Override - public boolean isValid(String pText) { - return pText.equalsIgnoreCase("valid"); - } - }); - } - - private void submitForm() { - if (validateFields()) { - Snackbar.make(fab, "Replace with your own action", Snackbar.LENGTH_LONG) - .show(); - } else { - Snackbar.make(fab, "Check form for errors", Snackbar.LENGTH_LONG) - .setAction("Retry", new View.OnClickListener() { - @Override - public void onClick(View v) { - submitForm(); - } - }) - .show(); - } - } - - private boolean validateFields() { - boolean flag = true; - if (!mUsernameInput.validate()) { - flag = false; - } - if (!mPasswordInput.validate()) flag = false; - if (!mEmailInput.validate()) flag = false; - if (!mConfPasswordInput.validate()) flag = false; - if (!mCustomInput.validate()) flag = false; - return flag; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.menu_main, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - - //noinspection SimplifiableIfStatement - if (id == R.id.action_settings) { - return true; - } - - return super.onOptionsItemSelected(item); - } -} diff --git a/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt b/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt new file mode 100644 index 0000000..6a21e09 --- /dev/null +++ b/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt @@ -0,0 +1,81 @@ +package com.julianraj.validatedtextinputlayoutsample + +import android.os.Bundle +import android.view.Menu +import android.view.MenuItem +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.snackbar.Snackbar +import com.julianraj.validatedtextinputlayout.validator.BaseValidator +import com.julianraj.validatedtextinputlayout.validator.DependencyValidator +import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.android.synthetic.main.content_main.* + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + setSupportActionBar(toolbar) + + fab.setOnClickListener { submitForm() } + + password.isCounterEnabled = true + val dependencyValidator = DependencyValidator(password, + DependencyValidator.Companion.DependencyType.TYPE_EQUAL, + "Confirmation password does not match the password.") + + confirmationPassword.addValidator(dependencyValidator) + + custom.addValidator(object : BaseValidator("Only accepts the word 'Valid'", + { status -> + if (!status) + Toast.makeText(this@MainActivity, "Your validation callback was called.", + Toast.LENGTH_SHORT).show() + }) { + override fun isValid(text: String): Boolean { + return text.equals("valid", ignoreCase = true) + } + }) + } + + private fun submitForm() { + if (validateFields()) { + Snackbar.make(fab, "Replace with your own action", Snackbar.LENGTH_LONG) + .show() + } else { + Snackbar.make(fab, "Check form for errors", Snackbar.LENGTH_LONG) + .setAction("Retry") { submitForm() } + .show() + } + } + + private fun validateFields(): Boolean { + var flag = true + if (!username.validate()) { + flag = false + } + if (!password.validate()) flag = false + if (!email.validate()) flag = false + if (!confirmationPassword.validate()) flag = false + if (!custom.validate()) flag = false + return flag + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + // Inflate the menu; this adds items to the action bar if it is present. + menuInflater.inflate(R.menu.menu_main, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + val id = item.itemId + return if (id == R.id.action_settings) { + true + } else super.onOptionsItemSelected(item) + + } +} diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index 6796e47..9d46c55 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - - - - + - - + diff --git a/sample/src/main/res/layout/content_main.xml b/sample/src/main/res/layout/content_main.xml index 9d2b1f1..23a52a7 100644 --- a/sample/src/main/res/layout/content_main.xml +++ b/sample/src/main/res/layout/content_main.xml @@ -1,5 +1,5 @@ - - - - - - - + diff --git a/validatedtextinputlayout/build.gradle b/validatedtextinputlayout/build.gradle index bebb5a8..570e3bc 100644 --- a/validatedtextinputlayout/build.gradle +++ b/validatedtextinputlayout/build.gradle @@ -1,5 +1,9 @@ apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + ext { bintrayRepo = 'maven' bintrayName = 'validatedtextinputlayout' @@ -26,12 +30,11 @@ ext { } android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + compileSdkVersion 29 defaultConfig { - minSdkVersion 9 - targetSdkVersion 25 + minSdkVersion 19 + targetSdkVersion 29 versionCode 1 versionName "0.3.0" } @@ -44,10 +47,10 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' - testCompile "org.mockito:mockito-core:1.10.19" - compile 'com.android.support:design:25.3.1' + implementation fileTree(dir: 'libs', include: ['*.jar']) + testImplementation 'junit:junit:4.12' + testImplementation "org.mockito:mockito-core:1.10.19" + implementation 'com.google.android.material:material:1.0.0' } if (project.rootProject.file('local.properties').exists()) { diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.java deleted file mode 100644 index f73c7f9..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.java +++ /dev/null @@ -1,246 +0,0 @@ -package com.julianraj.validatedtextinputlayout; - -import android.content.Context; -import android.content.res.TypedArray; -import android.support.design.widget.TextInputLayout; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.AttributeSet; - -import com.julianraj.validatedtextinputlayout.validator.BaseValidator; -import com.julianraj.validatedtextinputlayout.validator.IValidator; -import com.julianraj.validatedtextinputlayout.validator.LengthValidator; -import com.julianraj.validatedtextinputlayout.validator.RegexValidator; -import com.julianraj.validatedtextinputlayout.validator.RequiredValidator; - -import java.util.ArrayList; -import java.util.List; - -/** - * Extension of Android Design Library's {@link TextInputLayout} - *

This class enable you to add validation to the TextInputLayout - * - * @author Julian Raj Manandhar - */ -public class ValidatedTextInputLayout extends TextInputLayout { - private List mValidators; - private boolean mAutoValidate = false; - private boolean mAutoTrimValue = false; - private boolean mErrorAlwaysEnabled = true; - - public ValidatedTextInputLayout(Context context) { - super(context); - initialize(); - } - - public ValidatedTextInputLayout(Context context, AttributeSet attrs) { - super(context, attrs); - initialize(); - initializeCustomAttrs(context, attrs); - } - - public ValidatedTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initialize(); - initializeCustomAttrs(context, attrs); - } - - private void initialize() { - if (!isInEditMode()) { - mValidators = new ArrayList<>(); - this.post(new Runnable() { - @Override - public void run() { - if (!getEditText().isInEditMode()) - initializeTextWatcher(); - } - }); - } - } - - private void initializeCustomAttrs(Context context, AttributeSet attrs) { - if (!isInEditMode()) { - TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable - .ValidatedInputTextLayout, 0, 0); - - try { - mAutoTrimValue = typedArray.getBoolean(R.styleable.ValidatedInputTextLayout_autoTrim, - false); - mAutoValidate = typedArray.getBoolean(R.styleable - .ValidatedInputTextLayout_autoValidate, false); - mErrorAlwaysEnabled = typedArray.getBoolean(R.styleable - .ValidatedInputTextLayout_errorAlwaysEnabled, true); - - initRequiredValidation(context, typedArray); - initLengthValidation(context, typedArray); - initRegexValidation(context, typedArray); - } finally { - typedArray.recycle(); - } - } - } - - private void initRequiredValidation(Context context, TypedArray typedArray) { - if (typedArray.getBoolean(R.styleable.ValidatedInputTextLayout_isRequired, false)) { - String errorMessage = typedArray.getString(R.styleable - .ValidatedInputTextLayout_requiredValidationMessage); - if (errorMessage == null) - errorMessage = context.getString(R.string.default_required_validation_message); - addValidator(new RequiredValidator(errorMessage)); - } - } - - private void initLengthValidation(Context context, TypedArray typedArray) { - int minLength = typedArray.getInteger(R.styleable.ValidatedInputTextLayout_minLength, - LengthValidator.LENGTH_ZERO); - int maxLength = typedArray.getInteger(R.styleable.ValidatedInputTextLayout_maxLength, - LengthValidator.LENGTH_INDEFINITE); - - if (!(minLength == LengthValidator.LENGTH_ZERO && maxLength == LengthValidator - .LENGTH_INDEFINITE)) { - String errorMessage = typedArray.getString(R.styleable - .ValidatedInputTextLayout_lengthValidationMessage); - if (errorMessage == null) { - if (minLength == LengthValidator.LENGTH_ZERO) { - errorMessage = context.getString(R.string - .default_required_length_message_max, maxLength); - } else if (maxLength == LengthValidator.LENGTH_INDEFINITE) { - errorMessage = context.getString(R.string - .default_required_length_message_min, minLength); - } else { - errorMessage = context.getString(R.string - .default_required_length_message_min_max, minLength, maxLength); - } - } - addValidator(new LengthValidator(minLength, maxLength, errorMessage)); - } - } - - private void initRegexValidation(Context context, TypedArray typedArray) { - String regex = typedArray.getString(R.styleable.ValidatedInputTextLayout_regex); - if (regex != null) { - String errorMessage = typedArray.getString(R.styleable - .ValidatedInputTextLayout_regexValidationMessage); - if (errorMessage == null) - errorMessage = context.getString(R.string.default_regex_validation_message); - addValidator(new RegexValidator(regex, errorMessage)); - } - } - - private void initializeTextWatcher() { - getEditText().addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - if (isAutoValidated()) validate(); - else setError(null); - } - - @Override - public void afterTextChanged(Editable s) { - } - }); - } - - /** - * Clears all the validators associated with the {@link ValidatedTextInputLayout}. - */ - public void clearValidators() { - mValidators.clear(); - setErrorEnabled(false); - } - - /** - * Associates new {@link IValidator} with the {@link ValidatedTextInputLayout}. - * - * @param pValidator new validator to be associated with the input field - */ - public void addValidator(BaseValidator pValidator) { - mValidators.add(pValidator); - } - - /** - * Enable or disable auto-validation for the {@link ValidatedTextInputLayout}. - * - * @param flag flag to enable or disable auto-validation - */ - public void autoValidate(boolean flag) { - mAutoValidate = flag; - } - - /** - * @return if auto-validation is enabled - */ - public boolean isAutoValidated() { - return mAutoValidate; - } - - /** - * Enable or disable auto-trimming of the value of the input field for the - * {@link ValidatedTextInputLayout}. - *

Enabling will remove any leading and trailing white space from the value of field.

- *

Caution: You may not want to enable this in case of password fields.

- * - * @param flag flag to enable or disable auto-trimming of value - */ - public void autoTrimValue(boolean flag) { - mAutoTrimValue = flag; - } - - /** - * Flag to always enable error for the {@link TextInputLayout} - *

Enabled by default.

- *

Disabling will remove the error space below the Field once the validate method returns - * true. - * .

- * - * @param errorAlwaysEnabled flag to set error-space as always enabled - */ - public void setErrorAlwaysEnabled(boolean errorAlwaysEnabled) { - mErrorAlwaysEnabled = errorAlwaysEnabled; - } - - /** - * @return if auto-trimming input field value is enabled - */ - public boolean isAutoTrimEnabled() { - return mAutoTrimValue; - } - - /** - * Return a boolean which can be used to check the validity of the field. - * - * @return boolean indicating if the field is valid or not. - */ - public boolean validate() { - boolean status = true; - String text = getValue(); - for (BaseValidator validator : mValidators) { - if (!validator.validate(text)) { - setErrorEnabled(true); - setError(validator.getErrorMessage()); - status = false; - break; - } else { - setError(null); - } - } - if (status && !mErrorAlwaysEnabled) setErrorEnabled(false); - return status; - } - - /** - * Return a String value of the input field. - *

This method will remove white spaces if auto-trimming is enabled.

- * - * @return the value of the input field - * @see #autoTrimValue(boolean) - */ - public String getValue() { - if (isAutoTrimEnabled()) return getEditText().getText().toString().trim(); - else return getEditText().getText().toString(); - } -} \ No newline at end of file diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.kt new file mode 100644 index 0000000..b5a0b32 --- /dev/null +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/ValidatedTextInputLayout.kt @@ -0,0 +1,230 @@ +package com.julianraj.validatedtextinputlayout + +import android.content.Context +import android.content.res.TypedArray +import android.text.Editable +import android.text.TextWatcher +import android.util.AttributeSet + +import com.google.android.material.textfield.TextInputLayout +import com.julianraj.validatedtextinputlayout.validator.BaseValidator +import com.julianraj.validatedtextinputlayout.validator.LengthValidator +import com.julianraj.validatedtextinputlayout.validator.RegexValidator +import com.julianraj.validatedtextinputlayout.validator.RequiredValidator + +import java.util.ArrayList + +/** + * Extension of Android Design Library's [TextInputLayout] + * + * This class enable you to add validation to the TextInputLayout + * + * @author Julian Raj Manandhar + */ +class ValidatedTextInputLayout : TextInputLayout { + private var validators: MutableList? = null + /** + * @return if auto-validation is enabled + */ + var isAutoValidated = false + private set + /** + * @return if auto-trimming input field value is enabled + */ + var isAutoTrimEnabled = false + private set + + /** + * Flag to always enable error for the [TextInputLayout] + * + * Enabled by default. + * + * Disabling will remove the error space below the Field once the validate method returns + * true. + * */ + private var errorAlwaysEnabled = true + + /** + * Return a String value of the input field. + * + * This method will remove white spaces if auto-trimming is enabled. + * + * @return the value of the input field + * @see .autoTrimValue + */ + val value: String + get() = if (isAutoTrimEnabled) + editText!!.text.toString().trim { it <= ' ' } + else + editText!!.text.toString() + + constructor(context: Context) : super(context) { + initialize() + } + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { + initialize() + initializeCustomAttrs(context, attrs) + } + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { + initialize() + initializeCustomAttrs(context, attrs) + } + + private fun initialize() { + if (!isInEditMode) { + validators = ArrayList() + this.post { + if (!editText!!.isInEditMode) + initializeTextWatcher() + } + } + } + + private fun initializeCustomAttrs(context: Context, attrs: AttributeSet) { + if (!isInEditMode) { + val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable + .ValidatedInputTextLayout, 0, 0) + + try { + isAutoTrimEnabled = typedArray.getBoolean(R.styleable.ValidatedInputTextLayout_autoTrim, + false) + isAutoValidated = typedArray.getBoolean(R.styleable + .ValidatedInputTextLayout_autoValidate, false) + errorAlwaysEnabled = typedArray.getBoolean(R.styleable + .ValidatedInputTextLayout_errorAlwaysEnabled, true) + + initRequiredValidation(context, typedArray) + initLengthValidation(context, typedArray) + initRegexValidation(context, typedArray) + } finally { + typedArray.recycle() + } + } + } + + private fun initRequiredValidation(context: Context, typedArray: TypedArray) { + if (typedArray.getBoolean(R.styleable.ValidatedInputTextLayout_isRequired, false)) { + var errorMessage = typedArray.getString(R.styleable + .ValidatedInputTextLayout_requiredValidationMessage) + if (errorMessage == null) + errorMessage = context.getString(R.string.default_required_validation_message) + addValidator(RequiredValidator(errorMessage)) + } + } + + private fun initLengthValidation(context: Context, typedArray: TypedArray) { + val minLength = typedArray.getInteger(R.styleable.ValidatedInputTextLayout_minLength, + LengthValidator.LENGTH_ZERO) + val maxLength = typedArray.getInteger(R.styleable.ValidatedInputTextLayout_maxLength, + LengthValidator.LENGTH_INDEFINITE) + + if (!(minLength == LengthValidator.LENGTH_ZERO && maxLength == LengthValidator + .LENGTH_INDEFINITE)) { + var errorMessage = typedArray.getString(R.styleable + .ValidatedInputTextLayout_lengthValidationMessage) + if (errorMessage == null) { + if (minLength == LengthValidator.LENGTH_ZERO) { + errorMessage = context.getString(R.string + .default_required_length_message_max, maxLength) + } else if (maxLength == LengthValidator.LENGTH_INDEFINITE) { + errorMessage = context.getString(R.string + .default_required_length_message_min, minLength) + } else { + errorMessage = context.getString(R.string + .default_required_length_message_min_max, minLength, maxLength) + } + } + addValidator(LengthValidator(minLength, maxLength, errorMessage)) + } + } + + private fun initRegexValidation(context: Context, typedArray: TypedArray) { + val regex = typedArray.getString(R.styleable.ValidatedInputTextLayout_regex) + if (regex != null) { + var errorMessage = typedArray.getString(R.styleable + .ValidatedInputTextLayout_regexValidationMessage) + if (errorMessage == null) + errorMessage = context.getString(R.string.default_regex_validation_message) + addValidator(RegexValidator(regex, errorMessage)) + } + } + + private fun initializeTextWatcher() { + editText!!.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + if (isAutoValidated) + validate() + else + error = null + } + + override fun afterTextChanged(s: Editable) {} + }) + } + + /** + * Clears all the validators associated with the [ValidatedTextInputLayout]. + */ + fun clearValidators() { + validators!!.clear() + isErrorEnabled = false + } + + /** + * Associates new Validator with the [ValidatedTextInputLayout]. + * + * @param pValidator new validator to be associated with the input field + */ + fun addValidator(pValidator: BaseValidator) { + validators!!.add(pValidator) + } + + /** + * Enable or disable auto-validation for the [ValidatedTextInputLayout]. + * + * @param flag flag to enable or disable auto-validation + */ + fun autoValidate(flag: Boolean) { + isAutoValidated = flag + } + + /** + * Enable or disable auto-trimming of the value of the input field for the + * [ValidatedTextInputLayout]. + * + * Enabling will remove any leading and trailing white space from the value of field. + * + * Caution: You may not want to enable this in case of password fields. + * + * @param flag flag to enable or disable auto-trimming of value + */ + fun autoTrimValue(flag: Boolean) { + isAutoTrimEnabled = flag + } + + /** + * Return a boolean which can be used to check the validity of the field. + * + * @return boolean indicating if the field is valid or not. + */ + fun validate(): Boolean { + var status = true + val text = value + for (validator in validators!!) { + if (!validator.validate(text)) { + isErrorEnabled = true + error = validator.errorMessage + status = false + break + } else { + error = null + } + } + if (status && !errorAlwaysEnabled) isErrorEnabled = false + return status + } +} \ No newline at end of file diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.java deleted file mode 100644 index 06c35fd..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.julianraj.validatedtextinputlayout.validator; - -import android.support.annotation.NonNull; - -import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout; - -/** - * Base Validator class to inherit from for custom validation. - */ -public abstract class BaseValidator implements IValidator { - - /** - * Error message that will be displayed if validation fails. - *

This field must be set via constructor of the Custom Validation class.

- */ - protected String mErrorMessage; - - protected ValidationCallback mCallback; - - /** - * Sole constructor. (For invocation by subclass constructors) - * - * @param pErrorMessage error message to display if validation fails - */ - public BaseValidator(@NonNull String pErrorMessage) { - setErrorMessage(pErrorMessage); - } - - public BaseValidator(@NonNull String errorMessage, ValidationCallback callback) { - mErrorMessage = errorMessage; - mCallback = callback; - } - - /** - * Validate the associated {@link ValidatedTextInputLayout}. - * Also call the callback method if {@link ValidationCallback} is provided - * - * @param pText value associated with the input field - * @return validity of the field - */ - public boolean validate(String pText) { - boolean status = isValid(pText); - - if (mCallback != null) - mCallback.onValidation(status); - - return status; - } - - /** - * Check if the associated {@link ValidatedTextInputLayout} is valid or not. - * - * @param pText value associated with the input field - * @return validity of the field - */ - @Override - public abstract boolean isValid(String pText); - - /** - * Sets the error message to display if the validation fails. - * - * @param pErrorMessage error message to display if validation fails - */ - @Override - public void setErrorMessage(@NonNull String pErrorMessage) { - mErrorMessage = pErrorMessage; - } - - /** - * Get the error message associated with the {@link BaseValidator} - * - * @return error message - */ - @Override - public String getErrorMessage() { - return mErrorMessage; - } - - public void setCallback(ValidationCallback callback) { - mCallback = callback; - } -} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt new file mode 100644 index 0000000..7f95bcb --- /dev/null +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt @@ -0,0 +1,38 @@ +package com.julianraj.validatedtextinputlayout.validator + +import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout + +/** + * Base Validator class to inherit from for custom validation. + * + * @param errorMessage Error message that will be displayed if validation fails. + * @param callback callback with validation result + * + */ +abstract class BaseValidator(val errorMessage: String, + val callback: ((Boolean)-> Unit)? = null) { + + /** + * Validate the associated [ValidatedTextInputLayout]. + * Also call the callback method if it is provided + * + * @param text value associated with the input field + * + * @return validity of the field + */ + fun validate(text: String): Boolean { + val status = isValid(text) + + callback?.invoke(status) + + return status + } + + /** + * Check if the associated [ValidatedTextInputLayout] is valid or not. + * + * @param text value associated with the input field + * @return validity of the field + */ + abstract fun isValid(text: String): Boolean +} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.java deleted file mode 100644 index 64bc698..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.julianraj.validatedtextinputlayout.validator; - -import android.support.annotation.IntDef; -import android.support.annotation.NonNull; - -import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Created by julian on 3/10/16. - */ -public class DependencyValidator extends BaseValidator { - - /** - * Denotes the value of the field must be equal to that of dependent field. - */ - public static final int TYPE_EQUAL = 0; - /** - * Denotes the field to be required only if the value of dependent field is present. - *

i.e. if dependentField.getValue() is not empty.

- */ - public static final int TYPE_REQUIRED_IF_EXISTS = 1; - - /** - * Dependent Field - */ - final private ValidatedTextInputLayout mDependstOn; - - /** - * Denotes the dependency type for the field. - */ - final private int mDependencyType; - - - /** - * @param pDependsOn field for dependency - * @param pDependencyType type of dependency between the fields (must be one of #TYPE_EQUAL - * or TYPE_REQUIRED_IF_EXISTS) - * @param pErrorMessage error message to display if validation fails - */ - public DependencyValidator(@NonNull ValidatedTextInputLayout pDependsOn, @DependencyType int - pDependencyType, @NonNull String pErrorMessage) { - super(pErrorMessage); - mDependstOn = pDependsOn; - mDependencyType = pDependencyType; - } - - /** - * @param pDependsOn field for dependency - * @param pDependencyType type of dependency between the fields (must be one of #TYPE_EQUAL - * or TYPE_REQUIRED_IF_EXISTS) - * @param pErrorMessage error message to display if validation fails - * @param pCallback callback for validation event - */ - public DependencyValidator(@NonNull ValidatedTextInputLayout pDependsOn, @DependencyType int - pDependencyType, @NonNull String pErrorMessage, ValidationCallback pCallback) { - super(pErrorMessage, pCallback); - mDependstOn = pDependsOn; - mDependencyType = pDependencyType; - } - - @Override - public boolean isValid(String pText) { - if (mDependencyType == TYPE_EQUAL) { - return pText.equals(mDependstOn.getValue()); - } else if (mDependencyType == TYPE_REQUIRED_IF_EXISTS) { - return mDependstOn.getValue().isEmpty() ? true : !pText.isEmpty(); - } - return false; - } - - @IntDef({TYPE_EQUAL, TYPE_REQUIRED_IF_EXISTS}) - @Retention(RetentionPolicy.SOURCE) - public @interface DependencyType { - } -} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt new file mode 100644 index 0000000..6ffa316 --- /dev/null +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt @@ -0,0 +1,49 @@ +package com.julianraj.validatedtextinputlayout.validator + +import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout + +/** + * Dependency Validator which checks dependency on other ValidatedTextInputLayout + * + * @param dependsOn Dependent Field + * @param dependencyType Type of dependency between the fields (must be one of #TYPE_EQUAL + * or TYPE_REQUIRED_IF_EXISTS) + * @param errorMessage Error message that will be displayed if validation fails. + * @param callback callback with validation result + */ +class DependencyValidator(private val dependsOn: ValidatedTextInputLayout, + private val dependencyType: DependencyType, + errorMessage: String, + callback: ((Boolean)-> Unit)? = null) : + BaseValidator(errorMessage, callback) { + + override fun isValid(text: String): Boolean { + return when (dependencyType) { + DependencyType.TYPE_EQUAL -> text == dependsOn.value + DependencyType.TYPE_EQUAL_IGNORE_CASE -> text.equals(dependsOn.value, true) + DependencyType.TYPE_REQUIRED_IF_EXISTS -> { + if (dependsOn.value.isEmpty()) true else text.isNotEmpty() + } + } + } + + companion object { + enum class DependencyType { + /** + * Denotes the value of the field must be equal to that of dependent field. + */ + TYPE_EQUAL, + /** + * Denotes the value of the field must be equal to that of dependent field but + * ingores the text-case. + */ + TYPE_EQUAL_IGNORE_CASE, + /** + * Denotes the field to be required only if the value of dependent field is present. + * + * i.e. if dependentField.getValue() is not empty. + */ + TYPE_REQUIRED_IF_EXISTS + } + } +} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/IValidator.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/IValidator.java deleted file mode 100644 index 2893e7e..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/IValidator.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.julianraj.validatedtextinputlayout.validator; - -/** - * Interface to implement for custom validation - */ -public interface IValidator { - boolean isValid(String pText); - void setErrorMessage(String pErrorMessage); - String getErrorMessage(); -} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.java deleted file mode 100644 index 38977d5..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.julianraj.validatedtextinputlayout.validator; - -import android.support.annotation.NonNull; - -import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout; - -/** - * Validator to set length constraints to the associated {@link ValidatedTextInputLayout} - * - * @see BaseValidator - */ -public class LengthValidator extends BaseValidator { - - /** - * Default value for {@link #mMaximumLength} - *

This sets the length to be unlimited.

- */ - public static final int LENGTH_INDEFINITE = -1; - - /** - * Default value for {@link #mMinimumLength} - */ - public static final int LENGTH_ZERO = 0; - - /** - * Minimum length that the value of field must be. - */ - private int mMinimumLength = LENGTH_ZERO; - - /** - * Maximum length that the value of field can be. - */ - private int mMaximumLength = LENGTH_INDEFINITE; - - /** - * @param pErrorMessage error message to display if validation fails - */ - public LengthValidator(@NonNull String pErrorMessage) { - super(pErrorMessage); - } - - /** - * @param pMaximumLength maximum length that the value of field can be - * @param pErrorMessage error message to display if validation fails - */ - public LengthValidator(int pMaximumLength, @NonNull String pErrorMessage) { - super(pErrorMessage); - mMaximumLength = pMaximumLength; - } - - /** - * @param pMinimumLength minimum length that the value of field must be - * @param pMaximumLength maximum length that the value of field can be - * @param pErrorMessage error message to display if validation fails - */ - public LengthValidator(int pMinimumLength, int pMaximumLength, @NonNull String pErrorMessage) { - super(pErrorMessage); - mMinimumLength = pMinimumLength; - mMaximumLength = pMaximumLength; - } - - /** - * @param pErrorMessage error message to display if validation fails - * @param pCallback callback for validation event - */ - public LengthValidator(@NonNull String pErrorMessage, ValidationCallback pCallback) { - super(pErrorMessage, pCallback); - } - - /** - * @param pMaximumLength maximum length that the value of field can be - * @param pErrorMessage error message to display if validation fails - * @param pCallback callback for validation event - */ - public LengthValidator(int pMaximumLength, @NonNull String pErrorMessage, - ValidationCallback pCallback) { - super(pErrorMessage, pCallback); - mMaximumLength = pMaximumLength; - } - - /** - * @param pMinimumLength minimum length that the value of field must be - * @param pMaximumLength maximum length that the value of field can be - * @param pErrorMessage error message to display if validation fails - * @param pCallback callback for validation event - */ - public LengthValidator(int pMinimumLength, int pMaximumLength, @NonNull String pErrorMessage, - ValidationCallback pCallback) { - super(pErrorMessage, pCallback); - mMinimumLength = pMinimumLength; - mMaximumLength = pMaximumLength; - } - - /** - * Check if the associated {@link ValidatedTextInputLayout} meets the length constraint - * associated with it. - * - * @param pText value associated with the input field - * @return validity of the field - */ - @Override - public boolean isValid(String pText) { - int length = pText.length(); - if (getMaximumLength() == LENGTH_INDEFINITE) { - return length >= getMinimumLength(); - } else { - return (length >= getMinimumLength() && length <= getMaximumLength()); - } - } - - /** - * @param pMinimumLength minimum required length - */ - public void setMinimumLength(int pMinimumLength) { - mMinimumLength = pMinimumLength; - } - - /** - * @param pMaximumLength maximum valid length - */ - public void setMaximumLength(int pMaximumLength) { - mMaximumLength = pMaximumLength; - } - - public int getMinimumLength() { - return mMinimumLength; - } - - public int getMaximumLength() { - return mMaximumLength; - } -} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt new file mode 100644 index 0000000..e26d328 --- /dev/null +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt @@ -0,0 +1,49 @@ +package com.julianraj.validatedtextinputlayout.validator + +import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout + +/** + * Validator to set length constraints to the associated [ValidatedTextInputLayout] + * + * @param minimumLength Minimum length that the value of field must be. + * @param maximumLength Maximum length that the value of field can be. + * @param errorMessage Error message that will be displayed if validation fails. + * @param callback callback with validation result + * + * @see BaseValidator + */ +class LengthValidator(private val minimumLength: Int = LENGTH_ZERO, + private val maximumLength: Int = LENGTH_INDEFINITE, + errorMessage: String, + callback: ((Boolean)-> Unit)? = null) : BaseValidator(errorMessage, callback) { + + /** + * Check if the associated [ValidatedTextInputLayout] meets the length constraint + * associated with it. + * + * @param text value associated with the input field + * @return validity of the field + */ + override fun isValid(text: String): Boolean { + val length = text.length + return if (maximumLength == LENGTH_INDEFINITE) { + length >= minimumLength + } else { + length in minimumLength..maximumLength + } + } + + companion object { + /** + * Default value for [maximumLength] + * + * This sets the length to be unlimited. + */ + const val LENGTH_INDEFINITE = -1 + + /** + * Default value for [minimumLength] + */ + const val LENGTH_ZERO = 0 + } +} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.java deleted file mode 100644 index d4348b4..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.julianraj.validatedtextinputlayout.validator; - -import android.support.annotation.NonNull; - -import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout; - -import java.util.regex.Pattern; - -/** - * Validator to check if value satisfies given regular expression - * @see BaseValidator - */ -public class RegexValidator extends BaseValidator { - - final String mRegex; - - /** - * @param pRegex regular expression to check against - * @param pErrorMessage error message to display if validation fails - */ - public RegexValidator(@NonNull String pRegex, @NonNull String pErrorMessage) { - super(pErrorMessage); - mRegex = pRegex; - } - - /** - * @param pRegex regular expression to check against - * @param pErrorMessage error message to display if validation fails - * @param pCallback callback for validation event - */ - public RegexValidator(@NonNull String pRegex, @NonNull String pErrorMessage, - ValidationCallback pCallback) { - super(pErrorMessage, pCallback); - mRegex = pRegex; - } - - /** - * Check if the associated {@link ValidatedTextInputLayout} has correct value. - * - * @param pText value associated with the input field - * @return validity of the field - */ - @Override - public boolean isValid(String pText) { - return Pattern.compile(mRegex, Pattern.CASE_INSENSITIVE).matcher(pText).find(); - } -} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt new file mode 100644 index 0000000..eb48cb5 --- /dev/null +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt @@ -0,0 +1,29 @@ +package com.julianraj.validatedtextinputlayout.validator + +import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout + +import java.util.regex.Pattern + +/** + * Validator to check if value satisfies given regular expression + * + * @param regex regular expression to check against + * @param errorMessage Error message that will be displayed if validation fails. + * @param callback callback with validation result + * + * @see BaseValidator + */ +class RegexValidator(private val regex: String, + errorMessage: String, + callback: ((Boolean)-> Unit)? = null) : BaseValidator(errorMessage, callback) { + + /** + * Check if the associated [ValidatedTextInputLayout] has correct value. + * + * @param text value associated with the input field + * @return validity of the field + */ + override fun isValid(text: String): Boolean { + return Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(text).find() + } +} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.java deleted file mode 100644 index 6df434a..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.julianraj.validatedtextinputlayout.validator; - -import android.support.annotation.NonNull; - -import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout; - -/** - * Validator to set input field as required. - * @see BaseValidator - */ -public class RequiredValidator extends BaseValidator { - - /** - * @param pErrorMessage error message to display if validation fails - */ - public RequiredValidator(String pErrorMessage) { - super(pErrorMessage); - } - - /** - * @param pErrorMessage error message to display if validation fails - * @param pCallback callback for validation event - */ - public RequiredValidator(@NonNull String pErrorMessage, ValidationCallback pCallback) { - super(pErrorMessage, pCallback); - } - - /** - * Check if the associated {@link ValidatedTextInputLayout} is empty or not. - * - * @param pText value associated with the input field - * @return validity of the field - */ - @Override - public boolean isValid(String pText) { - return !pText.isEmpty(); - } -} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt new file mode 100644 index 0000000..6088cbf --- /dev/null +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt @@ -0,0 +1,25 @@ +package com.julianraj.validatedtextinputlayout.validator + +import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout + +/** + * Validator to set input field as required. + * + * @param errorMessage Error message that will be displayed if validation fails. + * @param callback callback with validation result + * + * @see BaseValidator + */ +class RequiredValidator(errorMessage: String, + callback: ((Boolean)-> Unit)? = null) : BaseValidator(errorMessage, callback) { + + /** + * Check if the associated [ValidatedTextInputLayout] is empty or not. + * + * @param text value associated with the input field + * @return validity of the field + */ + override fun isValid(text: String): Boolean { + return text.isNotEmpty() + } +} diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.java b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.java deleted file mode 100644 index e5a01cb..0000000 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.julianraj.validatedtextinputlayout.validator; - -/** - * Interface to implement for callback for validation events - */ - -public interface ValidationCallback { - void onValidation(boolean status); -} diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java index 2e92dc9..a50ef39 100644 --- a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java +++ b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java @@ -21,7 +21,7 @@ public class BaseValidatorTest { public void setUp() throws Exception { mValidator = new BaseValidator(ERROR_MESSAGE) { @Override - public boolean isValid(String pText) { + public boolean isValid(String text) { return false; } }; diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java index 3a3aa80..dea6fe6 100644 --- a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java +++ b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java @@ -36,12 +36,12 @@ public void setUp() throws Exception { @Test public void lengthValidator_ReturnsTrue() { - mValidator.setMaximumLength(LengthValidator.LENGTH_INDEFINITE); + mValidator.setMaximumLength(LengthValidator.Companion.getLENGTH_INDEFINITE()); mValidator.setMinimumLength(MIN_LENGTH); assertThat(mValidator.isValid(CORRECT_SAMPLE), is(true)); mValidator.setMaximumLength(MAX_LENGTH); - mValidator.setMinimumLength(LengthValidator.LENGTH_ZERO); + mValidator.setMinimumLength(LengthValidator.Companion.getLENGTH_ZERO()); assertThat(mValidator.isValid(CORRECT_SAMPLE), is(true)); mValidator.setMaximumLength(MAX_LENGTH); From f708ef560ab37f4789bbbed76c5284107dc6e59a Mon Sep 17 00:00:00 2001 From: Julian Date: Fri, 6 Sep 2019 17:24:55 -0400 Subject: [PATCH 2/4] correct test cases after kotlin migration --- .../MainActivity.kt | 11 ++-- validatedtextinputlayout/build.gradle | 6 +- .../validator/BaseValidator.kt | 4 +- .../validator/DependencyValidator.kt | 2 +- .../validator/LengthValidator.kt | 17 +++-- .../validator/RegexValidator.kt | 2 +- .../validator/RequiredValidator.kt | 3 +- .../validator/ValidationCallback.kt | 5 ++ .../BaseValidatorTest.java | 34 ---------- .../BaseValidatorTest.kt | 36 +++++++++++ .../LengthValidatorTest.java | 61 ------------------ .../LengthValidatorTest.kt | 62 +++++++++++++++++++ .../RegexValidatorTest.java | 45 -------------- .../RegexValidatorTest.kt | 50 +++++++++++++++ .../RequiredValidatorTest.java | 46 -------------- .../RequiredValidatorTest.kt | 50 +++++++++++++++ .../org.mockito.plugins.MockMaker | 1 + 17 files changed, 233 insertions(+), 202 deletions(-) create mode 100644 validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.kt delete mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java create mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.kt delete mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java create mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.kt delete mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.java create mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.kt delete mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.java create mode 100644 validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.kt create mode 100644 validatedtextinputlayout/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt b/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt index 6a21e09..42a45d0 100644 --- a/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt +++ b/sample/src/main/java/com/julianraj/validatedtextinputlayoutsample/MainActivity.kt @@ -8,6 +8,7 @@ import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar import com.julianraj.validatedtextinputlayout.validator.BaseValidator import com.julianraj.validatedtextinputlayout.validator.DependencyValidator +import com.julianraj.validatedtextinputlayout.validator.ValidationCallback import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.content_main.* @@ -28,10 +29,12 @@ class MainActivity : AppCompatActivity() { confirmationPassword.addValidator(dependencyValidator) custom.addValidator(object : BaseValidator("Only accepts the word 'Valid'", - { status -> - if (!status) - Toast.makeText(this@MainActivity, "Your validation callback was called.", - Toast.LENGTH_SHORT).show() + object : ValidationCallback { + override fun onValidation(status: Boolean) { + if (!status) + Toast.makeText(this@MainActivity, "Your validation callback was called.", + Toast.LENGTH_SHORT).show() + } }) { override fun isValid(text: String): Boolean { return text.equals("valid", ignoreCase = true) diff --git a/validatedtextinputlayout/build.gradle b/validatedtextinputlayout/build.gradle index 570e3bc..b3e8d0d 100644 --- a/validatedtextinputlayout/build.gradle +++ b/validatedtextinputlayout/build.gradle @@ -18,7 +18,7 @@ ext { siteUrl = 'https://github.com/julianraj/ValidatedTextInputLayout' gitUrl = 'https://github.com/julianraj/ValidatedTextInputLayout.git' - libraryVersion = '0.3.0' + libraryVersion = '1.0.0' developerId = 'julianraj' developerName = 'Julian Raj Manandhar' @@ -36,7 +36,7 @@ android { minSdkVersion 19 targetSdkVersion 29 versionCode 1 - versionName "0.3.0" + versionName "1.0.0" } buildTypes { release { @@ -49,7 +49,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation 'junit:junit:4.12' - testImplementation "org.mockito:mockito-core:1.10.19" + testImplementation "org.mockito:mockito-core:3.0.0" implementation 'com.google.android.material:material:1.0.0' } diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt index 7f95bcb..d6be038 100644 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/BaseValidator.kt @@ -10,7 +10,7 @@ import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout * */ abstract class BaseValidator(val errorMessage: String, - val callback: ((Boolean)-> Unit)? = null) { + val callback: ValidationCallback? = null) { /** * Validate the associated [ValidatedTextInputLayout]. @@ -23,7 +23,7 @@ abstract class BaseValidator(val errorMessage: String, fun validate(text: String): Boolean { val status = isValid(text) - callback?.invoke(status) + callback?.onValidation(status) return status } diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt index 6ffa316..e76d86d 100644 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/DependencyValidator.kt @@ -14,7 +14,7 @@ import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout class DependencyValidator(private val dependsOn: ValidatedTextInputLayout, private val dependencyType: DependencyType, errorMessage: String, - callback: ((Boolean)-> Unit)? = null) : + callback: ValidationCallback? = null) : BaseValidator(errorMessage, callback) { override fun isValid(text: String): Boolean { diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt index e26d328..d6adb6c 100644 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/LengthValidator.kt @@ -15,7 +15,16 @@ import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout class LengthValidator(private val minimumLength: Int = LENGTH_ZERO, private val maximumLength: Int = LENGTH_INDEFINITE, errorMessage: String, - callback: ((Boolean)-> Unit)? = null) : BaseValidator(errorMessage, callback) { + callback: ValidationCallback? = null) : BaseValidator(errorMessage, callback) { + + val minLength: Int + get() { + return minimumLength + } + val maxLength: Int + get() { + return maximumLength + } /** * Check if the associated [ValidatedTextInputLayout] meets the length constraint @@ -26,10 +35,10 @@ class LengthValidator(private val minimumLength: Int = LENGTH_ZERO, */ override fun isValid(text: String): Boolean { val length = text.length - return if (maximumLength == LENGTH_INDEFINITE) { - length >= minimumLength + return if (maxLength == LENGTH_INDEFINITE) { + length >= minLength } else { - length in minimumLength..maximumLength + length in minLength..maxLength } } diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt index eb48cb5..dd5cbd6 100644 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RegexValidator.kt @@ -15,7 +15,7 @@ import java.util.regex.Pattern */ class RegexValidator(private val regex: String, errorMessage: String, - callback: ((Boolean)-> Unit)? = null) : BaseValidator(errorMessage, callback) { + callback: ValidationCallback? = null) : BaseValidator(errorMessage, callback) { /** * Check if the associated [ValidatedTextInputLayout] has correct value. diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt index 6088cbf..7e9fb39 100644 --- a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/RequiredValidator.kt @@ -11,7 +11,8 @@ import com.julianraj.validatedtextinputlayout.ValidatedTextInputLayout * @see BaseValidator */ class RequiredValidator(errorMessage: String, - callback: ((Boolean)-> Unit)? = null) : BaseValidator(errorMessage, callback) { + callback: ValidationCallback? = null +) : BaseValidator(errorMessage, callback) { /** * Check if the associated [ValidatedTextInputLayout] is empty or not. diff --git a/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.kt b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.kt new file mode 100644 index 0000000..afb90a9 --- /dev/null +++ b/validatedtextinputlayout/src/main/java/com/julianraj/validatedtextinputlayout/validator/ValidationCallback.kt @@ -0,0 +1,5 @@ +package com.julianraj.validatedtextinputlayout.validator + +interface ValidationCallback { + fun onValidation(status: Boolean) +} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java deleted file mode 100644 index a50ef39..0000000 --- a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.julianraj.validatedtextinputlayout; - -import com.julianraj.validatedtextinputlayout.validator.BaseValidator; - -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class BaseValidatorTest { - - BaseValidator mValidator; - - public static final String ERROR_MESSAGE = "I am error message."; - - @Before - public void setUp() throws Exception { - mValidator = new BaseValidator(ERROR_MESSAGE) { - @Override - public boolean isValid(String text) { - return false; - } - }; - } - - @Test - public void baseValidator_Constructor() { - assertThat(mValidator.getErrorMessage(), is(ERROR_MESSAGE)); - } -} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.kt b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.kt new file mode 100644 index 0000000..115bbbf --- /dev/null +++ b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/BaseValidatorTest.kt @@ -0,0 +1,36 @@ +package com.julianraj.validatedtextinputlayout + +import com.julianraj.validatedtextinputlayout.validator.BaseValidator + +import org.junit.Before +import org.junit.Test + +import org.hamcrest.core.Is.`is` +import org.junit.Assert.assertThat + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +class BaseValidatorTest { + + lateinit var validator: BaseValidator + + @Before + @Throws(Exception::class) + fun setUp() { + validator = object : BaseValidator(ERROR_MESSAGE) { + override fun isValid(text: String): Boolean { + return false + } + } + } + + @Test + fun baseValidator_Constructor() { + assertThat(validator.errorMessage, `is`(ERROR_MESSAGE)) + } + + companion object { + const val ERROR_MESSAGE = "I am error message." + } +} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java deleted file mode 100644 index dea6fe6..0000000 --- a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.julianraj.validatedtextinputlayout; - -import com.julianraj.validatedtextinputlayout.validator.LengthValidator; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.withSettings; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class LengthValidatorTest { - - @Mock - LengthValidator mValidator; - - public static final int MIN_LENGTH = 4; - public static final int MAX_LENGTH = 10; - - public static final String CORRECT_SAMPLE = "test me"; - public static final String INCORRECT_SAMPLE1 = "me"; - public static final String INCORRECT_SAMPLE2 = "test me wrong"; - - @Before - public void setUp() throws Exception { - //MockitoAnnotations.initMocks(this); - mValidator = mock(LengthValidator.class, withSettings().defaultAnswer(CALLS_REAL_METHODS)); - } - - @Test - public void lengthValidator_ReturnsTrue() { - mValidator.setMaximumLength(LengthValidator.Companion.getLENGTH_INDEFINITE()); - mValidator.setMinimumLength(MIN_LENGTH); - assertThat(mValidator.isValid(CORRECT_SAMPLE), is(true)); - - mValidator.setMaximumLength(MAX_LENGTH); - mValidator.setMinimumLength(LengthValidator.Companion.getLENGTH_ZERO()); - assertThat(mValidator.isValid(CORRECT_SAMPLE), is(true)); - - mValidator.setMaximumLength(MAX_LENGTH); - mValidator.setMinimumLength(MIN_LENGTH); - assertThat(mValidator.isValid(CORRECT_SAMPLE), is(true)); - } - - @Test - public void lengthValidator_ReturnsFalse() { - assertThat(mValidator.isValid(INCORRECT_SAMPLE1), is(false)); - assertThat(mValidator.isValid(INCORRECT_SAMPLE2), is(false)); - } - - @After - public void tearDown() throws Exception { - } -} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.kt b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.kt new file mode 100644 index 0000000..e61a948 --- /dev/null +++ b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/LengthValidatorTest.kt @@ -0,0 +1,62 @@ +package com.julianraj.validatedtextinputlayout + +import com.julianraj.validatedtextinputlayout.validator.LengthValidator +import org.hamcrest.core.Is.`is` +import org.junit.After +import org.junit.Assert.assertThat +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.* + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +class LengthValidatorTest { + + @Mock + var validator: LengthValidator? = null + + @Before + @Throws(Exception::class) + fun setUp() { + //MockitoAnnotations.initMocks(this); + validator = mock(LengthValidator::class.java, withSettings().defaultAnswer(CALLS_REAL_METHODS)) + } + + @Test + fun lengthValidator_ReturnsTrue() { + `when`(validator!!.maxLength).thenReturn(LengthValidator.LENGTH_INDEFINITE) + `when`(validator!!.minLength).thenReturn(MIN_LENGTH) + assertThat(validator!!.isValid(CORRECT_SAMPLE), `is`(true)) + + `when`(validator!!.maxLength).thenReturn(MAX_LENGTH) + `when`(validator!!.minLength).thenReturn(LengthValidator.LENGTH_ZERO) + assertThat(validator!!.isValid(CORRECT_SAMPLE), `is`(true)) + + `when`(validator!!.maxLength).thenReturn(MAX_LENGTH) + `when`(validator!!.minLength).thenReturn(MIN_LENGTH) + assertThat(validator!!.isValid(CORRECT_SAMPLE), `is`(true)) + } + + @Test + fun lengthValidator_ReturnsFalse() { + assertThat(validator!!.isValid(INCORRECT_SAMPLE1), `is`(false)) + assertThat(validator!!.isValid(INCORRECT_SAMPLE2), `is`(false)) + } + + @After + @Throws(Exception::class) + fun tearDown() { + } + + companion object { + + const val MIN_LENGTH = 4 + const val MAX_LENGTH = 10 + + const val CORRECT_SAMPLE = "test me" + const val INCORRECT_SAMPLE1 = "me" + const val INCORRECT_SAMPLE2 = "test me wrong" + } +} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.java b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.java deleted file mode 100644 index bf234fe..0000000 --- a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.julianraj.validatedtextinputlayout; - -import com.julianraj.validatedtextinputlayout.validator.RegexValidator; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class RegexValidatorTest { - - public static final String REGEX = "^[a-z]+@[0-9]{2,}$"; - public static final String CORRECT_SAMPLE1 = "asd@123"; - public static final String CORRECT_SAMPLE2 = "asdASD@12"; - public static final String INCORRECT_SAMPLE1 = "012@1"; - public static final String INCORRECT_SAMPLE2 = "as@1"; - - RegexValidator mValidator; - - @Before - public void setUp() throws Exception { - mValidator = new RegexValidator(REGEX, "error message."); - } - - @Test - public void regexValidator_ReturnsTrue() { - assertThat(mValidator.isValid(CORRECT_SAMPLE1), is(true)); - assertThat(mValidator.isValid(CORRECT_SAMPLE2), is(true)); - } - - @Test - public void regexValidator_ReturnsFalse() { - assertThat(mValidator.isValid(INCORRECT_SAMPLE1), is(false)); - assertThat(mValidator.isValid(INCORRECT_SAMPLE2), is(false)); - } - - @After - public void tearDown() throws Exception { - } -} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.kt b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.kt new file mode 100644 index 0000000..1018a1f --- /dev/null +++ b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RegexValidatorTest.kt @@ -0,0 +1,50 @@ +package com.julianraj.validatedtextinputlayout + +import com.julianraj.validatedtextinputlayout.validator.RegexValidator + +import org.junit.After +import org.junit.Before +import org.junit.Test + +import org.hamcrest.core.Is.`is` +import org.junit.Assert.assertThat + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +class RegexValidatorTest { + + lateinit var mValidator: RegexValidator + + @Before + @Throws(Exception::class) + fun setUp() { + mValidator = RegexValidator(REGEX, "error message.") + } + + @Test + fun regexValidator_ReturnsTrue() { + assertThat(mValidator.isValid(CORRECT_SAMPLE1), `is`(true)) + assertThat(mValidator.isValid(CORRECT_SAMPLE2), `is`(true)) + } + + @Test + fun regexValidator_ReturnsFalse() { + assertThat(mValidator.isValid(INCORRECT_SAMPLE1), `is`(false)) + assertThat(mValidator.isValid(INCORRECT_SAMPLE2), `is`(false)) + } + + @After + @Throws(Exception::class) + fun tearDown() { + } + + companion object { + + const val REGEX = "^[a-z]+@[0-9]{2,}$" + const val CORRECT_SAMPLE1 = "asd@123" + const val CORRECT_SAMPLE2 = "asdASD@12" + const val INCORRECT_SAMPLE1 = "012@1" + const val INCORRECT_SAMPLE2 = "as@1" + } +} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.java b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.java deleted file mode 100644 index 1421499..0000000 --- a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.julianraj.validatedtextinputlayout; - -import com.julianraj.validatedtextinputlayout.validator.RequiredValidator; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.withSettings; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class RequiredValidatorTest { - - @Mock - RequiredValidator mValidator; - - public static final String CORRECT_SAMPLE = "test string"; - public static final String INCORRECT_SAMPLE1 = ""; - - @Before - public void setUp() throws Exception { - //MockitoAnnotations.initMocks(this); - mValidator = mock(RequiredValidator.class, withSettings().defaultAnswer(CALLS_REAL_METHODS)); - } - - @Test - public void requiredValidator_ReturnsTrue() { - assertThat(mValidator.isValid(CORRECT_SAMPLE), is(true)); - } - - @Test - public void requiredValidator_ReturnsFalse() { - assertThat(mValidator.isValid(INCORRECT_SAMPLE1), is(false)); - } - - @After - public void tearDown() throws Exception { - } -} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.kt b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.kt new file mode 100644 index 0000000..b785a5e --- /dev/null +++ b/validatedtextinputlayout/src/test/java/com/julianraj/validatedtextinputlayout/RequiredValidatorTest.kt @@ -0,0 +1,50 @@ +package com.julianraj.validatedtextinputlayout + +import com.julianraj.validatedtextinputlayout.validator.RequiredValidator + +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mockito.Mock + +import org.hamcrest.core.Is.`is` +import org.junit.Assert.assertThat +import org.mockito.Mockito.CALLS_REAL_METHODS +import org.mockito.Mockito.mock +import org.mockito.Mockito.withSettings + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +class RequiredValidatorTest { + + @Mock + var validator: RequiredValidator? = null + + @Before + @Throws(Exception::class) + fun setUp() { + //MockitoAnnotations.initMocks(this); + validator = mock(RequiredValidator::class.java, withSettings().defaultAnswer(CALLS_REAL_METHODS)) + } + + @Test + fun requiredValidator_ReturnsTrue() { + assertThat(validator!!.isValid(CORRECT_SAMPLE), `is`(true)) + } + + @Test + fun requiredValidator_ReturnsFalse() { + assertThat(validator!!.isValid(INCORRECT_SAMPLE1), `is`(false)) + } + + @After + @Throws(Exception::class) + fun tearDown() { + } + + companion object { + const val CORRECT_SAMPLE = "test string" + const val INCORRECT_SAMPLE1 = "" + } +} \ No newline at end of file diff --git a/validatedtextinputlayout/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/validatedtextinputlayout/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/validatedtextinputlayout/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file From 57a10444f4f17947c9cee2b497870d0ab188410b Mon Sep 17 00:00:00 2001 From: Julian Date: Fri, 6 Sep 2019 17:39:10 -0400 Subject: [PATCH 3/4] migrate to circleci 2 --- .circleci/config.yml | 31 +++++++++++++++++++++++++++++++ circle.yml | 20 -------------------- 2 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 .circleci/config.yml delete mode 100644 circle.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..39471cc --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,31 @@ +version: 2 + +jobs: + build: + working_directory: ~/code + docker: + - image: circleci/android:api-29 + environment: + JVM_OPTS: -Xmx3200m + steps: + - checkout + - restore_cache: + key: jars-{{ checksum "build.gradle" }}-{{ checksum "validatedtextinputlayout/build.gradle" }} + # - run: + # name: Chmod permissions #if permission for Gradlew Dependencies fail, use this. + # command: sudo chmod +x ./gradlew + - run: + name: Download Dependencies + command: ./gradlew androidDependencies + - save_cache: + paths: + - ~/.gradle + key: jars-{{ checksum "build.gradle" }}-{{ checksum "validatedtextinputlayout/build.gradle" }} + - run: + name: Run Tests + command: ./gradlew runUnitTests + - store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/ + path: validatedtextinputlayout/build/reports + destination: reports + - store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/ + path: validatedtextinputlayout/build/test-results diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 2591dcc..0000000 --- a/circle.yml +++ /dev/null @@ -1,20 +0,0 @@ -general: - artifacts: - - /home/ubuntu/your-app-name/app/build/outputs/apk/ - -machine: - java: - version: openjdk8 - environment: - ANDROID_HOME: /usr/local/android-sdk-linux - -dependencies: - pre: - - echo y | android update sdk --no-ui --all --filter tool,extra-android-m2repository,extra-android-support,extra-google-google_play_services,extra-google-m2repository,android-25 - - echo y | android update sdk --no-ui --all --filter build-tools-25.0.3 - -test: - override: - - (./gradlew assemble): - timeout: 360 - - ./gradlew runUnitTests \ No newline at end of file From 312eaaa8e70d186abd2cf45dee9981287ac5ea34 Mon Sep 17 00:00:00 2001 From: Julian Date: Fri, 6 Sep 2019 18:17:54 -0400 Subject: [PATCH 4/4] update README and library version to 1.0.0-beta1 --- README.md | 55 +++++++++++-------------- validatedtextinputlayout/bintray.gradle | 17 -------- validatedtextinputlayout/build.gradle | 4 +- 3 files changed, 27 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index d6ed013..b9bb7b8 100644 --- a/README.md +++ b/README.md @@ -7,39 +7,38 @@ ValidatedTextInputLayout [ ![Download](https://api.bintray.com/packages/julianra ## Demo ## ![Demo](./images/demo.gif) -**Note: library's package name has been corrected from validatedinputtextlayout to -validatedtextinputlayout in the latest version [You may want to update your xml files accordingly - on update]** +**Note: v1.0.0-beta1 adds migration to androidx and to kotlin from java. Upgrading to beta might +break your code.** ## Features ## - **AutoValidation** Validate the input field as the text changes. - `mInput.autoValidate(true);` + `input.autoValidate(true)` If `false` you need to call the `validate()` method explicitly for validation. OR use xml attribute `autoValidate` as true or false. - **AutoTrim** - `mInput.getValue()` will return the value of input field after removing leading and trailing + `input.getValue()` will return the value of input field after removing leading and trailing white spaces - `mInput.autoTrimValue(true);` + `input.autoTrimValue(true)` OR use xml attribute `autoTrim` as true or false. - **Add Validators** You can add multiple validators to a single input field. - `mInput.addValidator(/* Your first Validator class goes here */);` - `mInput.addValidator(/* Your second Validator class goes here */);` + `input.addValidator(/* Your first Validator class goes here */)` + `input.addValidator(/* Your second Validator class goes here */)` - **Clear Validators** Removes all the validators associated with the input field. - `mInput.clearValidators();` + `input.clearValidators()` - **Default Available Validators** + **RequiredValidator** Validates the input field as required. i.e. empty value is not valid. - `mInput.addValidator(new RequiredValidator("Your error message"));` + `input.addValidator(RequiredValidator("Your error message"))` OR use xml attribute `isRequired` as true or false. The default message will be "This field is required." @@ -47,8 +46,8 @@ validatedtextinputlayout in the latest version [You may want to update your xml + **LengthValidator** Validates the input field against minimum and maximum length specified. - `mInput.addValidator(new LengthValidator(8 /* Max Length */, "Your error message"));` - `mInput.addValidator(new LengthValidator(4 /* Min Length */, *8 /* Max Length */, "Your error message"));` + `input.addValidator(LengthValidator(8 /* Max Length */, "Your error message"))` + `input.addValidator(LengthValidator(4 /* Min Length */, *8 /* Max Length */, "Your error message"))` OR use xml attributes `minLength` and `maxLength` with default values being "zero" and "indefinite" respectively. The default message will be one of following @@ -59,7 +58,7 @@ validatedtextinputlayout in the latest version [You may want to update your xml For custom message you can use xml attribute `lengthValidationMessage` + **RegexValidator** Validates the input field against provided regular expression. Equivalent to `String.matches()` - `mInput.addValidator(new RegexValidator("your_regex", "Your error message"));` + `input.addValidator(new RegexValidator("your_regex", "Your error message"))` OR use xml attribute `regex` to set your regular expression. The default message will be "The field value does not match the required format." @@ -67,10 +66,10 @@ validatedtextinputlayout in the latest version [You may want to update your xml + **DependencyValidator** Validates the input field as per the dependency type with the input field it depends on. - If `mInput1` depends on `mInput2` with dependency type TYPE_EQUAL: (i.e. `mInput1 - .getValue()` must be equal to `mInput1.getValue()`) - `mInput1.addValidator(new DependencyValidator(mInput2, TYPE_EQUAL, "Your error - message"));` + If `input1` depends on `input2` with dependency type TYPE_EQUAL: (i.e. `input1 + .getValue()` must be equal to `input1.getValue()`) + `input1.addValidator(new DependencyValidator(input2, TYPE_EQUAL, "Your error + message"))` - **Custom Validators** You can create your own validators to use with ValidatedTextInputLayout just by extending the `BaseValidator` class. @@ -78,14 +77,10 @@ validatedtextinputlayout in the latest version [You may want to update your xml Example: Validator class to check if field value contains character sequence "xyz" - public class MyValidator extends BaseValidator { - public MyValidator(String pErrorMessage){ - super(pErrorMessage); - } - - @Override - public boolean isValid(String pText){ - return pText.contains("xyz"); + class MyValidator(errorMessage: String, + callback: ValidationCallback? = null): BaseValidator(errorMessage, callback) { + override fun isValid(text: String): Boolean { + return text.contains("xyz") } } @@ -100,13 +95,13 @@ validatedtextinputlayout in the latest version [You may want to update your xml com.julianraj validatedtextinputlayout - 0.3.0 + 1.0.0-beta1 pom - **Gradle** - compile 'com.julianraj:validatedtextinputlayout:0.3.0' + compile 'com.julianraj:validatedtextinputlayout:1.0.0-beta1' - You can use and style it similar to **Android Design Library's** _TextInputLayout_ @@ -119,7 +114,7 @@ validatedtextinputlayout in the latest version [You may want to update your xml validation:isRequired="true" validation:requiredValidationMessage="Your error message here."> - - - - variant.javaCompile.classpath.files - }) -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - artifacts { - archives javadocJar archives sourcesJar } diff --git a/validatedtextinputlayout/build.gradle b/validatedtextinputlayout/build.gradle index b3e8d0d..89a839e 100644 --- a/validatedtextinputlayout/build.gradle +++ b/validatedtextinputlayout/build.gradle @@ -18,7 +18,7 @@ ext { siteUrl = 'https://github.com/julianraj/ValidatedTextInputLayout' gitUrl = 'https://github.com/julianraj/ValidatedTextInputLayout.git' - libraryVersion = '1.0.0' + libraryVersion = '1.0.0-beta1' developerId = 'julianraj' developerName = 'Julian Raj Manandhar' @@ -36,7 +36,7 @@ android { minSdkVersion 19 targetSdkVersion 29 versionCode 1 - versionName "1.0.0" + versionName "1.0.0-beta1" } buildTypes { release {