summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--day9/task5_vue/backend/__init__.py0
-rw-r--r--day9/task5_vue/backend/core/__init__.py0
-rw-r--r--day9/task5_vue/backend/database/__init__.py0
-rw-r--r--day9/task5_vue/backend/database/field_types.py20
-rw-r--r--day9/task5_vue/backend/database/validators.py16
-rw-r--r--day9/task5_vue/package-lock.json443
-rw-r--r--day9/task5_vue/package.json2
-rw-r--r--day9/task5_vue/src/App.vue62
-rw-r--r--day9/task5_vue/src/components/EditFormBox.vue6
-rw-r--r--day9/task5_vue/src/components/PopupMessage.vue28
-rw-r--r--day9/task5_vue/src/components/Table.vue48
-rw-r--r--day9/task5_vue/tests/__init__.py0
-rw-r--r--day9/task5_vue/tests/test_db_validators.py124
-rw-r--r--day9/task5_vue/webpack.config.js8
15 files changed, 703 insertions, 55 deletions
diff --git a/.gitignore b/.gitignore
index b9e77e5..d6471f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.idea/
venv/
node_modules
+.pytest_cache
diff --git a/day9/task5_vue/backend/__init__.py b/day9/task5_vue/backend/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/day9/task5_vue/backend/__init__.py
diff --git a/day9/task5_vue/backend/core/__init__.py b/day9/task5_vue/backend/core/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/day9/task5_vue/backend/core/__init__.py
diff --git a/day9/task5_vue/backend/database/__init__.py b/day9/task5_vue/backend/database/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/day9/task5_vue/backend/database/__init__.py
diff --git a/day9/task5_vue/backend/database/field_types.py b/day9/task5_vue/backend/database/field_types.py
index d0b2c3b..8713882 100644
--- a/day9/task5_vue/backend/database/field_types.py
+++ b/day9/task5_vue/backend/database/field_types.py
@@ -12,7 +12,7 @@ class Field(ABC):
@property
@abstractmethod
- def sql_line(self):
+ def sql_line(self) -> str:
pass
def validate(self, value):
@@ -21,7 +21,7 @@ class Field(ABC):
class TextField(Field):
- def __init__(self, max_length, is_variable_length, nullable, default, validators=None):
+ def __init__(self, max_length, is_variable_length, nullable, default=None, validators=None):
super().__init__(validators)
self.max_length = max_length
@@ -45,7 +45,7 @@ class TextField(Field):
class IntegerField(Field):
- def __init__(self, max_length, nullable, is_auto_increment, default, validators=None):
+ def __init__(self, max_length, nullable, is_auto_increment, default=None, validators=None):
super().__init__(validators)
self.max_length = max_length
@@ -62,7 +62,7 @@ class IntegerField(Field):
'NULL' if self.nullable else 'NOT NULL'
]
- if self.default is not None:
+ if self.default is not None or self.nullable:
request.append(f'DEFAULT "{self.default}"')
if self.is_auto_increment:
@@ -72,7 +72,7 @@ class IntegerField(Field):
class DateField(Field):
- def __init__(self, nullable, default, validators=None):
+ def __init__(self, nullable, default=None, validators=None):
super().__init__(validators)
self.nullable = nullable
@@ -84,14 +84,14 @@ class DateField(Field):
def sql_line(self):
request = ['date', 'NULL' if self.nullable else 'NOT NULL']
- if self.default is not None:
+ if self.default is not None or self.nullable:
request.append(f'DEFAULT "{self.default}"')
return ' '.join(request)
class TimeField(Field):
- def __init__(self, nullable, default, validators=None):
+ def __init__(self, nullable, default=None, validators=None):
super().__init__(validators)
self.nullable = nullable
@@ -103,14 +103,14 @@ class TimeField(Field):
def sql_line(self):
request = ['time', 'NULL' if self.nullable else 'NOT NULL']
- if self.default is not None:
+ if self.default is not None or self.nullable:
request.append(f'DEFAULT "{self.default}"')
return ' '.join(request)
class DatetimeField(Field):
- def __init__(self, nullable, default, validators=None):
+ def __init__(self, nullable, default=None, validators=None):
super().__init__(validators)
self.nullable = nullable
@@ -122,7 +122,7 @@ class DatetimeField(Field):
def sql_line(self):
request = ['datetime', 'NULL' if self.nullable else 'NOT NULL']
- if self.default is not None:
+ if self.default is not None or self.nullable:
request.append(f'DEFAULT "{self.default}"')
return ' '.join(request)
diff --git a/day9/task5_vue/backend/database/validators.py b/day9/task5_vue/backend/database/validators.py
index e4b7310..112af2b 100644
--- a/day9/task5_vue/backend/database/validators.py
+++ b/day9/task5_vue/backend/database/validators.py
@@ -32,8 +32,12 @@ class ValidateType(Validator):
class ValidateLength(Validator):
@staticmethod
def validate(value, field_object):
+ if hasattr(field_object, 'is_variable_length') and not field_object.is_variable_length:
+ if len(str(value)) < field_object.max_length:
+ raise ValidationError('Value has too few characters')
+
if len(str(value)) > field_object.max_length:
- raise ValidationError('Value has too many digits')
+ raise ValidationError('Value has too many characters')
class ValidateTime(Validator):
@@ -65,14 +69,14 @@ class ValidateDate(Validator):
if year < 0:
raise ValidationError('Wrong year value')
- if month not in range(1, 12):
+ if month not in range(1, 12 + 1):
raise ValidationError('Wrong month value')
if month == 2:
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
- febr_range = range(1, 29)
+ febr_range = range(1, 29 + 1)
else:
- febr_range = range(1, 28)
+ febr_range = range(1, 28 + 1)
if day not in febr_range:
raise ValidationError('Wrong day value')
else:
@@ -81,7 +85,7 @@ class ValidateDate(Validator):
6: 30, 7: 31, 8: 31, 9: 30,
10: 31, 11: 30, 12: 31
}.get(month)
- if day not in range(1, days_count):
+ if day not in range(1, days_count + 1):
raise ValidationError('Wrong day value')
@@ -93,4 +97,4 @@ class ValidateDatetime(Validator):
raise ValidationError('Wrong datetime format')
else:
ValidateDate.validate(datetime[0], {})
- ValidateTime.validate(datetime[1], {}) \ No newline at end of file
+ ValidateTime.validate(datetime[1], {})
diff --git a/day9/task5_vue/package-lock.json b/day9/task5_vue/package-lock.json
index 7718c3d..2fdde82 100644
--- a/day9/task5_vue/package-lock.json
+++ b/day9/task5_vue/package-lock.json
@@ -463,6 +463,23 @@
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
},
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+ "dev": true,
+ "optional": true
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
"asn1.js": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
@@ -497,6 +514,13 @@
}
}
},
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true,
+ "optional": true
+ },
"assign-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
@@ -507,11 +531,32 @@
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
"integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
},
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true,
+ "optional": true
+ },
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
},
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true,
+ "optional": true
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+ "dev": true,
+ "optional": true
+ },
"axios": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
@@ -606,6 +651,16 @@
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
},
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -800,6 +855,13 @@
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true,
+ "optional": true
+ },
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -893,6 +955,12 @@
"wrap-ansi": "^5.1.0"
}
},
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ },
"collection-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -915,6 +983,16 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
@@ -1113,6 +1191,16 @@
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
"integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA="
},
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
"date-now": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
@@ -1180,6 +1268,13 @@
}
}
},
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true,
+ "optional": true
+ },
"des.js": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
@@ -1221,6 +1316,17 @@
"stream-shift": "^1.0.0"
}
},
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
"elliptic": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz",
@@ -1374,6 +1480,13 @@
"homedir-polyfill": "^1.0.1"
}
},
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true,
+ "optional": true
+ },
"extend-shallow": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
@@ -1452,6 +1565,13 @@
}
}
},
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true,
+ "optional": true
+ },
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
@@ -1550,6 +1670,25 @@
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
},
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true,
+ "optional": true
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
"fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -2084,6 +2223,16 @@
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
@@ -2161,6 +2310,24 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg=="
},
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true,
+ "optional": true
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ }
+ },
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -2244,6 +2411,18 @@
"parse-passwd": "^1.0.0"
}
},
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
"https-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
@@ -2268,6 +2447,13 @@
"resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE="
},
+ "image-size": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+ "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+ "dev": true,
+ "optional": true
+ },
"import-local": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
@@ -2443,6 +2629,13 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true,
+ "optional": true
+ },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -2469,11 +2662,25 @@
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
},
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true,
+ "optional": true
+ },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -2484,11 +2691,25 @@
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
},
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true,
+ "optional": true
+ },
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true,
+ "optional": true
+ },
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
@@ -2497,6 +2718,19 @@
"minimist": "^1.2.0"
}
},
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
@@ -2511,6 +2745,43 @@
"invert-kv": "^2.0.0"
}
},
+ "less": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz",
+ "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.2",
+ "errno": "^0.1.1",
+ "graceful-fs": "^4.1.2",
+ "image-size": "~0.5.0",
+ "mime": "^1.4.1",
+ "mkdirp": "^0.5.0",
+ "promise": "^7.1.1",
+ "request": "^2.83.0",
+ "source-map": "~0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "less-loader": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz",
+ "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.1",
+ "loader-utils": "^1.1.0",
+ "pify": "^4.0.1"
+ }
+ },
"loader-runner": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
@@ -2660,6 +2931,30 @@
"brorand": "^1.0.1"
}
},
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "optional": true
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+ "dev": true,
+ "optional": true
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -2844,6 +3139,13 @@
"path-key": "^2.0.0"
}
},
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true,
+ "optional": true
+ },
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -3038,6 +3340,13 @@
"sha.js": "^2.4.8"
}
},
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true,
+ "optional": true
+ },
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
@@ -3187,6 +3496,16 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
+ "promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asap": "~2.0.3"
+ }
+ },
"promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@@ -3203,6 +3522,13 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
"dev": true
},
+ "psl": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
+ "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
+ "dev": true,
+ "optional": true
+ },
"public-encrypt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
@@ -3251,6 +3577,13 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+ "dev": true,
+ "optional": true
+ },
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
@@ -3326,6 +3659,35 @@
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
},
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -3432,6 +3794,13 @@
"ret": "~0.1.10"
}
},
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "optional": true
+ },
"schema-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
@@ -3662,6 +4031,24 @@
"extend-shallow": "^3.0.0"
}
},
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
"ssri": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
@@ -3878,6 +4265,26 @@
"repeat-string": "^1.6.1"
}
},
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
"trim-right": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
@@ -3893,6 +4300,23 @@
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
},
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -4026,12 +4450,31 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+ "dev": true,
+ "optional": true
+ },
"v8-compile-cache": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz",
"integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==",
"dev": true
},
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
"vm-browserify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz",
diff --git a/day9/task5_vue/package.json b/day9/task5_vue/package.json
index 650d57a..d439908 100644
--- a/day9/task5_vue/package.json
+++ b/day9/task5_vue/package.json
@@ -19,6 +19,8 @@
"babel": "^6.23.0",
"babel-loader": "^8.0.6",
"css-loader": "^3.1.0",
+ "less": "^3.9.0",
+ "less-loader": "^5.0.0",
"vue-loader": "^15.7.1",
"vue-template-compiler": "^2.6.10",
"webpack-cli": "^3.3.6"
diff --git a/day9/task5_vue/src/App.vue b/day9/task5_vue/src/App.vue
index 2af8b20..8def105 100644
--- a/day9/task5_vue/src/App.vue
+++ b/day9/task5_vue/src/App.vue
@@ -2,13 +2,18 @@
<div>
<EditFormBox
v-bind:form-type="formType"
- v-bind:cancel-callback="hideForm"
v-bind:table-row="formData"
+ v-bind:cancel-callback="hideForm"
+ v-bind:show-popup="showPopup"
v-if="isFormShown"
/>
<Table v-bind:table-data="tableData" v-bind:show-form-callback="showForm"/>
<UploadFileButton v-if="!isFormShown"/>
<AddNewEntryButton v-if="!isFormShown" v-bind:show-form-callback="showForm"/>
+
+ <transition name="fade">
+ <PopupMessage v-if="isPopupShown" v-bind:message="popupMessage"/>
+ </transition>
</div>
</template>
@@ -17,35 +22,57 @@
import Table from "./components/Table.vue";
import UploadFileButton from "./components/UploadFileButton.vue";
import AddNewEntryButton from './components/AddNewEntryButton.vue';
+ import PopupMessage from './components/PopupMessage.vue'
+
import axios from 'axios';
+
export default {
name: "App",
- components: {EditFormBox, Table, UploadFileButton, AddNewEntryButton},
+ components: {PopupMessage, EditFormBox, Table, UploadFileButton, AddNewEntryButton},
data() {
return {
tableData: [],
formType: null,
formData: null,
- isFormShown: false
+ isFormShown: false,
+
+ isPopupShown: false,
+ popupMessage: '',
}
},
mounted() {
- axios
- .request({
- url: '/api/get/',
- method: 'post',
- headers: {'Content-Type': 'application/json'},
- data: JSON.stringify({'type': 'full'})
- })
- .then(response => {
- this.tableData = response.data;
- })
+ this.updateTable();
},
methods: {
+ updateTable() {
+ axios
+ .request({
+ url: '/api/get/',
+ method: 'post',
+ headers: {'Content-Type': 'application/json'},
+ data: JSON.stringify({'type': 'full'})
+ })
+ .then(response => {
+ this.tableData = response.data;
+ })
+ },
+
+ showPopup(message) {
+ if (!this.isPopupShown) {
+ this.isPopupShown = true;
+ this.popupMessage = message;
+
+ setTimeout(() => {
+ this.isPopupShown = false;
+ this.popupMessage = '';
+ }, 2000)
+ }
+ },
+
showForm(formType, formData) {
this.formType = formType;
this.formData = formData;
@@ -56,11 +83,18 @@
this.formType = null;
this.formData = null;
this.isFormShown = false;
+
+ this.updateTable()
}
}
}
</script>
<style scoped>
-
+ .fade-enter-active, .fade-leave-active {
+ transition: opacity .5s;
+ }
+ .fade-enter, .fade-leave-to {
+ opacity: 0;
+ }
</style> \ No newline at end of file
diff --git a/day9/task5_vue/src/components/EditFormBox.vue b/day9/task5_vue/src/components/EditFormBox.vue
index 861a82d..c994656 100644
--- a/day9/task5_vue/src/components/EditFormBox.vue
+++ b/day9/task5_vue/src/components/EditFormBox.vue
@@ -111,7 +111,7 @@
export default {
name: "EditFormBox",
- props: ['formType', 'cancelCallback', 'tableRow'],
+ props: ['formType', 'cancelCallback', 'tableRow', 'showPopup'],
data() {
return {
@@ -178,6 +178,10 @@
headers: {'Content-Type': 'application/json'},
data: JSON.stringify(formData)
})
+ .then(response => {
+ this.cancelCallback();
+ this.showPopup('Database updated successfully');
+ });
}
}
}
diff --git a/day9/task5_vue/src/components/PopupMessage.vue b/day9/task5_vue/src/components/PopupMessage.vue
new file mode 100644
index 0000000..a905b4d
--- /dev/null
+++ b/day9/task5_vue/src/components/PopupMessage.vue
@@ -0,0 +1,28 @@
+<template>
+ <div ref="container" class="popupContainer">
+ {{ message }}
+ </div>
+</template>
+
+<script>
+ export default {
+ name: "PopupMessage",
+ props: ['message'],
+ }
+</script>
+
+<style scoped>
+ .popupContainer {
+ background-color: #00ff5e;
+ padding: 30px;
+
+ font-size: 30px;
+ text-align: center;
+
+ position: fixed;
+ bottom: 0;
+
+ left: 0;
+ right: 0;
+ }
+</style> \ No newline at end of file
diff --git a/day9/task5_vue/src/components/Table.vue b/day9/task5_vue/src/components/Table.vue
index d9296d9..a186277 100644
--- a/day9/task5_vue/src/components/Table.vue
+++ b/day9/task5_vue/src/components/Table.vue
@@ -1,29 +1,29 @@
<template>
<table>
- <thead>
- <tr>
- <th v-for="header in tableData.headers">
- {{ header }}
- </th>
- <th></th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(row) in tableData.content">
- <td>{{ row[0] }}</td>
- <td v-for="(column) in row.slice(1)">
- {{ column }}
- </td>
- <td>
- <button @click="showEditForm(`${row[0]}`)">&#9998</button>
- </td>
- <td>
- <button @click="removeField(`${row[0]}`)">&#10006</button>
- </td>
- </tr>
- </tbody>
- </table>
+ <thead>
+ <tr>
+ <th v-for="header in tableData.headers">
+ {{ header }}
+ </th>
+ <th></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="(row) in tableData.content">
+ <td>{{ row[0] }}</td>
+ <td v-for="(column) in row.slice(1)">
+ {{ column }}
+ </td>
+ <td>
+ <button @click="showEditForm(`${row[0]}`)">&#9998</button>
+ </td>
+ <td>
+ <button @click="removeField(`${row[0]}`)">&#10006</button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
</template>
<script>
diff --git a/day9/task5_vue/tests/__init__.py b/day9/task5_vue/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/day9/task5_vue/tests/__init__.py
diff --git a/day9/task5_vue/tests/test_db_validators.py b/day9/task5_vue/tests/test_db_validators.py
new file mode 100644
index 0000000..b83fcf1
--- /dev/null
+++ b/day9/task5_vue/tests/test_db_validators.py
@@ -0,0 +1,124 @@
+from backend.database.validators import (
+ ValidateNull, ValidateType, ValidateTime,
+ ValidateDatetime, ValidateDate, ValidateLength,
+ ValidationError
+)
+from backend.database.field_types import (
+ TextField, IntegerField,
+ DatetimeField, DateField, TimeField
+)
+
+import pytest
+
+
+def test_validate_null():
+ field1 = IntegerField(None, nullable=False, is_auto_increment=False)
+ field2 = IntegerField(None, nullable=True, is_auto_increment=False)
+
+ with pytest.raises(ValidationError):
+ ValidateNull.validate(None, field1)
+
+ assert ValidateNull.validate(None, field2) is None
+
+
+def test_validate_type():
+ text1 = TextField(10, True, nullable=False)
+ text2 = TextField(10, True, nullable=True)
+
+ with pytest.raises(ValidationError):
+ ValidateType.validate(None, text1)
+
+ with pytest.raises(ValidationError):
+ ValidateType.validate(12, text1)
+
+ with pytest.raises(ValidationError):
+ ValidateType.validate({1, 2, 3}, text1)
+
+ with pytest.raises(ValidationError):
+ ValidateType.validate({1: 2}, text1)
+
+ assert ValidateType.validate('123', text1) is None
+ assert ValidateType.validate(None, text2) is None
+
+
+def test_validate_length():
+ text1 = TextField(10, is_variable_length=True, nullable=False)
+ text2 = TextField(10, is_variable_length=False, nullable=False)
+
+ assert ValidateLength.validate('1234567890', text1) is None
+ assert ValidateLength.validate('1234567890', text2) is None
+
+ with pytest.raises(ValidationError):
+ ValidateLength.validate('1234567890*', text1)
+
+ with pytest.raises(ValidationError):
+ ValidateLength.validate('123456789', text2)
+
+ assert ValidateLength.validate('123456789', text1) is None
+
+
+def test_validate_time():
+ time_field = TimeField(False)
+
+ assert ValidateTime.validate('00:00:00', time_field) is None
+ assert ValidateTime.validate('23:59:59', time_field) is None
+
+ with pytest.raises(ValidationError):
+ ValidateTime.validate('24:00:00', time_field)
+
+ with pytest.raises(ValidationError):
+ ValidateTime.validate('12:60:00', time_field)
+
+ with pytest.raises(ValidationError):
+ ValidateTime.validate('12:00:60', time_field)
+
+ with pytest.raises(ValidationError, match='Wrong time format'):
+ ValidateTime.validate('22:00', time_field)
+
+ with pytest.raises(ValidationError, match='Wrong time format'):
+ ValidateTime.validate('22:00 12', time_field)
+
+ with pytest.raises(ValidationError, match='Wrong time format'):
+ ValidateTime.validate('gsdfsd', time_field)
+
+
+def test_validate_date():
+ date_field = DateField(False)
+
+ assert ValidateDate.validate('0001-01-01', date_field) is None
+ assert ValidateDate.validate('9999-12-31', date_field) is None
+
+ with pytest.raises(ValidationError):
+ ValidateDate.validate('0000-00-00', date_field)
+
+ with pytest.raises(ValidationError, match='Wrong day value'):
+ ValidateDate.validate('2019-02-29', date_field)
+
+ assert ValidateDate.validate('2020-02-29', date_field) is None
+
+ with pytest.raises(ValidationError):
+ ValidateDate.validate('2019-02-30', date_field)
+
+ with pytest.raises(ValidationError, match='Wrong date format'):
+ ValidateDate.validate('17-03-21', date_field)
+
+ with pytest.raises(ValidationError, match='Wrong date format'):
+ ValidateDate.validate('2002.03.12', date_field)
+
+ with pytest.raises(ValidationError, match='Wrong date format'):
+ ValidateDate.validate('gsdfsd', date_field)
+
+
+def test_validate_datetime():
+ datetime_field = DatetimeField(False)
+
+ assert ValidateDatetime.validate('2002-04-25 20:03:12', datetime_field) is None
+
+ with pytest.raises(ValidationError):
+ ValidateDatetime.validate('2002-04-25_20:03:12', datetime_field)
+
+ with pytest.raises(ValidationError):
+ ValidateDatetime.validate('2002 04 25 20:03:12', datetime_field)
+
+ with pytest.raises(ValidationError):
+ ValidateDatetime.validate('2002-04-25 20:03', datetime_field)
diff --git a/day9/task5_vue/webpack.config.js b/day9/task5_vue/webpack.config.js
index 38efa45..6a7390a 100644
--- a/day9/task5_vue/webpack.config.js
+++ b/day9/task5_vue/webpack.config.js
@@ -20,6 +20,14 @@ module.exports = {
'vue-style-loader',
'css-loader'
]
+ },
+ {
+ test: /\.less$/,
+ use: [
+ 'vue-style-loader',
+ 'css-loader',
+ 'less-loader'
+ ]
}
]
},