Skip to content

Tests/add linting #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
root: true,

extends: ['eslint:recommended', 'plugin:unicorn/recommended', 'prettier'],

rules: {
'unicorn/no-reduce': ['off'],
},
};
9 changes: 9 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const jestCommon = require('./test/config/jest.common');
const lintProject = require('./test/config/jest.lint');
const unitTestProject = require('./test/config/jest.unit');

module.exports = {
...jestCommon,

projects: [unitTestProject, lintProject],
};
2 changes: 1 addition & 1 deletion lib/components/Form.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script>
import {setContext} from 'svelte';
import {createForm} from '../createForm';
import {createForm} from '../create-form';
import {key} from './key';

export let initialValues = {};
Expand Down
113 changes: 68 additions & 45 deletions lib/createForm.js → lib/create-form.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { derived, writable } from "svelte/store";
import { util } from "./util";
import {derived, writable} from 'svelte/store';
import {util} from './util';

const NO_ERROR = "";
const NO_ERROR = '';
const IS_TOUCHED = true;

function isCheckbox(element) {
return element.getAttribute && element.getAttribute('type') === 'checkbox';
}

export const createForm = config => {
let initialValues = config.initialValues || {};

Expand All @@ -18,7 +22,7 @@ export const createForm = config => {
const getInitial = {
values: () => util.cloneDeep(initialValues),
errors: () => util.assignDeep(initialValues, NO_ERROR),
touched: () => util.assignDeep(initialValues, !IS_TOUCHED)
touched: () => util.assignDeep(initialValues, !IS_TOUCHED),
};

const form = writable(getInitial.values());
Expand All @@ -37,29 +41,25 @@ export const createForm = config => {
});

const modified = derived(form, $form => {
const obj = util.assignDeep($form, false);
const object = util.assignDeep($form, false);

for (let key in $form) {
if ($form[key] !== initialValues[key]) {
obj[key] = true;
object[key] = true;
}
}

return obj;
return object;
});

const isModified = derived(modified, $modified => {
return util.getValues($modified).some(field => field === true);
});

function isCheckbox(el) {
return el.getAttribute && el.getAttribute('type') === 'checkbox';
}

function validateField(field) {
return util.subscribeOnce(form).then((values) =>
validateFieldValue(field, values[field])
);
return util
.subscribeOnce(form)
.then(values => validateFieldValue(field, values[field]));
}

function validateFieldValue(field, value) {
Expand All @@ -70,8 +70,8 @@ export const createForm = config => {
return util
.reach(validationSchema, field)
.validate(value)
.then(() => util.update(errors, field, ""))
.catch(err => util.update(errors, field, err.message))
.then(() => util.update(errors, field, ''))
.catch(error => util.update(errors, field, error.message))
.finally(() => {
isValidating.set(false);
});
Expand All @@ -80,11 +80,11 @@ export const createForm = config => {
if (validateFn) {
isValidating.set(true);
return Promise.resolve()
.then(() => validateFn({ [field]: value }))
.then(() => validateFn({[field]: value}))
.then(errs => util.update(errors, field, errs[field]))
.finally(() => {
isValidating.set(false);
})
});
}
}

Expand All @@ -94,11 +94,10 @@ export const createForm = config => {
});
}


function handleChange(event) {
const el = event.target;
const field = el.name || el.id;
const value = isCheckbox(el) ? el.checked : el.value;
const element = event.target;
const field = element.name || element.id;
const value = isCheckbox(element) ? element.checked : element.value;

return updateValidateField(field, value);
}
Expand All @@ -111,32 +110,37 @@ export const createForm = config => {
isSubmitting.set(true);

return util.subscribeOnce(form).then(values => {
if (typeof validateFn === "function") {
if (typeof validateFn === 'function') {
isValidating.set(true);

return Promise.resolve()
.then(() => validateFn(values))
.then(err =>
util.isEmpty(err) ? clearErrorsAndSubmit(values) : errors.set(err)
.then(error =>
util.isEmpty(error)
? clearErrorsAndSubmit(values)
: errors.set(error),
)
.finally(() => isValidating.set(false));
}

if (validationSchema) {
isValidating.set(true);

return validationSchema
.validate(values, { abortEarly: false })
.then(() => clearErrorsAndSubmit(values))
.catch(yupErrs => {
if (yupErrs && yupErrs.inner) {
yupErrs.inner.forEach(error =>
util.update(errors, error.path, error.message)
);
}
isSubmitting.set(false);
})
.finally(() => isValidating.set(false));
return (
validationSchema
.validate(values, {abortEarly: false})
.then(() => clearErrorsAndSubmit(values))
// eslint-disable-next-line unicorn/catch-error-name
.catch(yupErrors => {
if (yupErrors && yupErrors.inner) {
yupErrors.inner.forEach(error =>
util.update(errors, error.path, error.message),
);
}
isSubmitting.set(false);
})
.finally(() => isValidating.set(false))
);
}

clearErrorsAndSubmit(values);
Expand All @@ -151,7 +155,7 @@ export const createForm = config => {

function clearErrorsAndSubmit(values) {
return Promise.resolve()
.then(() => errors.set(util.assignDeep(values, "")))
.then(() => errors.set(util.assignDeep(values, '')))
.then(() => onSubmit(values, form, errors))
.finally(() => isSubmitting.set(false));
}
Expand All @@ -171,11 +175,12 @@ export const createForm = config => {
}

function isInitialValuesValid() {
if (Object.keys(initialValues).length < 1) {
if (Object.keys(initialValues).length === 0) {
const provided = JSON.stringify(initialValues);

// eslint-disable-next-line no-undef
console.warn(
`createForm requires initialValues to be a non empty object or array, provided ${provided}`
`createForm requires initialValues to be a non empty object or array, provided ${provided}`,
);

return false;
Expand Down Expand Up @@ -215,17 +220,35 @@ export const createForm = config => {
validateField,
updateInitialValues,
state: derived(
[form, errors, touched, modified, isValid, isValidating, isSubmitting, isModified],
([$form, $errors, $touched, $modified, $isValid, $isValidating, $isSubmitting, $isModified]) => ({
[
form,
errors,
touched,
modified,
isValid,
isValidating,
isSubmitting,
isModified,
],
([
$form,
$errors,
$touched,
$modified,
$isValid,
$isValidating,
$isSubmitting,
$isModified,
]) => ({
form: $form,
errors: $errors,
touched: $touched,
modified: $modified,
isValid: $isValid,
isSubmitting: $isSubmitting,
isValidating: $isValidating,
isModified: $isModified
})
)
isModified: $isModified,
}),
),
};
};
10 changes: 5 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { createForm } from "./createForm";
export { default as Form } from "./components/Form.svelte";
export { default as Field } from "./components/Field.svelte";
export { default as Select } from "./components/Select.svelte";
export { default as ErrorMessage } from "./components/ErrorMessage.svelte";
export {createForm} from './create-form';
export {default as Form} from './components/Form.svelte';
export {default as Field} from './components/Field.svelte';
export {default as Select} from './components/Select.svelte';
export {default as ErrorMessage} from './components/ErrorMessage.svelte';
Loading