Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
package_control_channel
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Gaurav Kukreja
package_control_channel
Commits
9729d15c
Commit
9729d15c
authored
Mar 17, 2015
by
FichteFoll
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4195 from wbond/some_tests_updates
Some tests updates
parents
23ee6ed4
b698ee82
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
153 additions
and
142 deletions
+153
-142
test.py
tests/test.py
+153
-142
No files found.
tests/test.py
View file @
9729d15c
...
...
@@ -27,11 +27,11 @@ if sys.version_info >= (3,):
generator_method_type
=
'method'
str_cls
=
str
else
:
from
.
import
unittest_compat
from
.
import
unittest_compat
# NOQA (monkeypatches the unittest module)
from
urlparse
import
urljoin
from
urllib2
import
HTTPError
,
urlopen
generator_method_type
=
'instancemethod'
str_cls
=
unicode
str_cls
=
unicode
# NOQA (obviously undefined in Py3)
if
hasattr
(
sys
,
'argv'
):
...
...
@@ -131,30 +131,6 @@ class TestContainer(object):
Does not contain tests itself, must be used as mixin with unittest.TestCase.
"""
package_key_types_map
=
{
'name'
:
str_cls
,
'details'
:
str_cls
,
'description'
:
str_cls
,
'releases'
:
list
,
'homepage'
:
str_cls
,
'author'
:
(
str_cls
,
list
),
'readme'
:
str_cls
,
'issues'
:
str_cls
,
'donate'
:
(
str_cls
,
type
(
None
)),
'buy'
:
str_cls
,
'previous_names'
:
list
,
'labels'
:
list
}
dependency_key_types_map
=
{
'name'
:
str_cls
,
'description'
:
str_cls
,
'releases'
:
list
,
'issues'
:
str_cls
,
'load_order'
:
str_cls
,
'author'
:
str_cls
}
rel_b_reg
=
r'''^ (https:// github\.com/ [^/]+/ [^/]+
|https:// bitbucket\.org/ [^/]+/ [^/]+
) $'''
...
...
@@ -234,10 +210,24 @@ class TestContainer(object):
self
.
assertRegex
(
line
,
r"^\t*\S"
,
"Indent must be tabs in line
%
d"
%
(
i
+
1
))
package_key_types_map
=
{
'name'
:
str_cls
,
'details'
:
str_cls
,
'description'
:
str_cls
,
'releases'
:
list
,
'homepage'
:
str_cls
,
'author'
:
(
str_cls
,
list
),
'readme'
:
str_cls
,
'issues'
:
str_cls
,
'donate'
:
(
str_cls
,
type
(
None
)),
'buy'
:
str_cls
,
'previous_names'
:
list
,
'labels'
:
list
}
def
_test_package
(
self
,
include
,
data
):
for
k
,
v
in
data
.
items
():
self
.
assertIn
(
k
,
self
.
package_key_types_map
)
self
.
assertIsInstance
(
v
,
self
.
package_key_types_map
[
k
],
k
)
self
.
enforce_key_types_map
(
k
,
v
,
self
.
package_key_types_map
)
if
k
==
'donate'
and
v
is
None
:
# Allow "removing" the donate url that is added by "details"
...
...
@@ -265,10 +255,18 @@ class TestContainer(object):
self
.
assertIn
(
key
,
data
,
'
%
r is required if no "details" URL '
'provided'
%
key
)
dependency_key_types_map
=
{
'name'
:
str_cls
,
'description'
:
str_cls
,
'releases'
:
list
,
'issues'
:
str_cls
,
'load_order'
:
str_cls
,
'author'
:
str_cls
}
def
_test_dependency
(
self
,
include
,
data
):
for
k
,
v
in
data
.
items
():
self
.
assertIn
(
k
,
self
.
dependency_key_types_map
)
self
.
assertIsInstance
(
v
,
self
.
dependency_key_types_map
[
k
],
k
)
self
.
enforce_key_types_map
(
k
,
v
,
self
.
dependency_key_types_map
)
if
k
==
'issues'
:
self
.
assertRegex
(
v
,
'^https?://'
)
...
...
@@ -283,31 +281,77 @@ class TestContainer(object):
self
.
assertRegex
(
v
,
'^
\
d
\
d$'
,
'"load_order" must be a two '
'digit string'
)
def
_test_release
(
self
,
package_name
,
data
,
main_repo
=
True
):
# Fail early
pck_release_key_types_map
=
{
'base'
:
str_cls
,
'tags'
:
(
bool
,
str_cls
),
'branch'
:
str_cls
,
'sublime_text'
:
str_cls
,
'platforms'
:
(
list
,
str_cls
),
'dependencies'
:
(
list
,
str_cls
),
'version'
:
str_cls
,
'date'
:
str_cls
,
'url'
:
str_cls
}
dep_release_key_types_map
=
{
'base'
:
str_cls
,
'tags'
:
(
bool
,
str_cls
),
'branch'
:
str_cls
,
'sublime_text'
:
str_cls
,
'platforms'
:
(
list
,
str_cls
),
'version'
:
str_cls
,
'sha256'
:
str_cls
,
'url'
:
str_cls
}
def
_test_release
(
self
,
package_name
,
data
,
dependency
,
main_repo
=
True
):
# Test for required keys (and fail early)
if
main_repo
:
self
.
assertTrue
((
'tags'
in
data
or
'branch'
in
data
),
'A release must have a "tags" key or "branch" key '
'if it is in the main repository. For custom '
'releases, a custom repository.json file must be '
'hosted elsewhere.'
)
for
req
in
(
'url'
,
'version'
,
'date'
):
self
.
assertNotIn
(
req
,
data
,
'The version, date and url keys should not be '
'used in the main repository since a pull '
'request would be necessary for every release'
)
if
dependency
:
condition
=
(
'tags'
in
data
or
'branch'
in
data
or
(
'sha256'
in
data
and
(
'url'
not
in
data
or
data
[
'url'
]
.
startswith
(
'http://'
)))
)
self
.
assertTrue
(
condition
,
'A release must have a "tags" key or "branch" key '
'if it is in the main repository. For custom '
'releases, a custom repository.json file must be '
'hosted elsewhere. The only exception to this rule '
'is for packages that can not be served over HTTPS '
'since they help bootstrap proper secure HTTP '
'support for Sublime Text.'
)
else
:
self
.
assertTrue
((
'tags'
in
data
or
'branch'
in
data
),
'A release must have a "tags" key or "branch" key '
'if it is in the main repository. For custom '
'releases, a custom repository.json file must be '
'hosted elsewhere.'
)
for
key
in
(
'url'
,
'version'
,
'date'
):
self
.
assertNotIn
(
key
,
data
,
'The version, date and url keys should not be '
'used in the main repository since a pull '
'request would be necessary for every release'
)
elif
'tags'
not
in
data
and
'branch'
not
in
data
:
self
.
assertTrue
(
all
(
k
in
data
for
k
in
(
'url'
,
'version'
,
'date'
)),
'A release must provide "url", "version" and '
'"date" keys if it does not specify "tags" or'
'"branch"'
)
if
dependency
:
for
key
in
(
'url'
,
'version'
):
self
.
assertIn
(
key
,
data
,
'A release must provide "url" and "version" '
'keys if it does not specify "tags" or "branch"'
)
else
:
for
key
in
(
'url'
,
'version'
,
'date'
):
self
.
assertIn
(
key
,
data
,
'A release must provide "url", "version" and '
'"date" keys if it does not specify "tags" or'
'"branch"'
)
else
:
for
req
in
(
'url'
,
'version'
,
'date'
):
self
.
assertNotIn
(
req
,
data
,
for
key
in
(
'url'
,
'version'
,
'date'
):
self
.
assertNotIn
(
key
,
data
,
'The key "
%
s" is redundant when "tags" or '
'"branch" is specified'
%
req
)
'"branch" is specified'
%
key
)
self
.
assertIn
(
'sublime_text'
,
data
,
'A sublime text version selector is required'
)
...
...
@@ -316,120 +360,82 @@ class TestContainer(object):
'A release must have a only one of the "tags" or '
'"branch" keys.'
)
for
k
,
v
in
data
.
items
():
self
.
assertIn
(
k
,
(
'base'
,
'tags'
,
'branch'
,
'sublime_text'
,
'platforms'
,
'version'
,
'date'
,
'url'
))
# Test keys values
self
.
check_release_key_values
(
data
,
dependency
)
if
k
==
'date'
:
self
.
assertRegex
(
v
,
r"^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$"
)
def
check_release_key_values
(
self
,
data
,
dependency
):
"""Check the key-value pairs of a release for validity."""
release_key_types_map
=
(
self
.
dep_release_key_types_map
if
dependency
else
self
.
pck_release_key_types_map
)
for
k
,
v
in
data
.
items
():
self
.
enforce_key_types_map
(
k
,
v
,
release_key_types_map
)
if
k
==
'url'
:
self
.
assertRegex
(
v
,
r'^https?://'
)
if
dependency
:
if
'sha256'
not
in
data
:
self
.
assertRegex
(
v
,
r'^https://'
)
else
:
self
.
assertRegex
(
v
,
r'^http://'
)
else
:
self
.
assertRegex
(
v
,
r'^https?://'
)
if
k
==
'base'
:
el
if
k
==
'base'
:
self
.
assertRegex
(
v
,
self
.
release_base_regex
,
'The base url is badly formatted or '
'invalid'
)
if
k
==
'tags'
:
self
.
assertIn
(
type
(
v
),
(
str_cls
,
bool
))
if
k
==
'branch'
:
self
.
assertEqual
(
type
(
v
),
str_cls
)
if
k
==
'sublime_text'
:
elif
k
==
'sublime_text'
:
self
.
assertRegex
(
v
,
'^(
\
*|<=?
\
d{4}|>=?
\
d{4})$'
,
'sublime_text must be `*` or of the form '
'<relation><version> '
'where <relation> is one of {<, <=, >, >=} '
'and <version> is a 4 digit number'
)
if
k
==
'platforms'
:
self
.
assertIsInstance
(
v
,
(
str_cls
,
list
))
elif
k
==
'platforms'
:
if
isinstance
(
v
,
str_cls
):
v
=
[
v
]
for
plat
in
v
:
self
.
assertRegex
(
plat
,
r"^\*|(osx|linux|windows)(-x(32|64))?$"
)
def
_test_dependency_release
(
self
,
package_name
,
data
,
main_repo
=
True
):
if
main_repo
:
self
.
assertTrue
((
'tags'
in
data
or
'branch'
in
data
or
(
'sha256'
in
data
and
'version'
in
data
and
'url'
in
data
and
data
[
'url'
][
0
:
7
]
==
'http://'
)),
'A release must have a "tags" key or "branch" key '
'if it is in the main repository. For custom '
'releases, a custom repository.json file must be '
'hosted elsewhere. The only exception to this rule '
'is for packages that can not be served over HTTPS '
'since they help bootstrap proper secure HTTP '
'support for Sublime Text.'
)
if
'sha256'
not
in
data
:
for
req
in
(
'url'
,
'version'
):
self
.
assertNotIn
(
req
,
data
,
'The version and url keys should not be '
'used in the main repository since a pull '
'request would be necessary for every '
'release.'
)
elif
'tags'
not
in
data
and
'branch'
not
in
data
:
for
req
in
(
'url'
,
'version'
):
self
.
assertIn
(
req
,
data
,
'A release must provide "url" and "version" '
'keys if it does not specify "tags" or "branch"'
)
else
:
if
'tags'
in
data
and
'branch'
in
data
:
self
.
fail
(
'Only one of the keys "tags" and "branch" should '
'be used'
)
for
req
in
(
'url'
,
'version'
):
self
.
assertNotIn
(
req
,
data
,
'The key "
%
s" is redundant when "tags" or '
'"branch" is specified'
%
req
)
self
.
assertIn
(
'sublime_text'
,
data
,
'A sublime text version selector is required'
)
for
k
,
v
in
data
.
items
():
self
.
assertIn
(
k
,
(
'base'
,
'tags'
,
'branch'
,
'sublime_text'
,
'platforms'
,
'version'
,
'url'
,
'sha256'
))
elif
k
==
'date'
:
self
.
assertRegex
(
v
,
r"^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$"
)
if
k
==
'url'
and
'sha256'
not
in
data
:
self
.
assertRegex
(
v
,
r'^https://'
)
elif
k
==
'url'
:
self
.
assertRegex
(
v
,
r'^http://'
)
self
.
assertRegex
(
v
,
r'^http
s?
://'
)
if
k
==
'base'
:
el
if
k
==
'base'
:
self
.
assertRegex
(
v
,
self
.
release_base_regex
,
'The base url is badly formatted or '
'invalid'
)
if
k
==
'tags'
:
self
.
assertIn
(
type
(
v
),
(
str_cls
,
bool
))
if
k
==
'branch'
:
self
.
assertEqual
(
type
(
v
),
str_cls
)
if
k
==
'sha256'
:
self
.
assertEqual
(
type
(
v
),
str_cls
)
if
k
==
'sublime_text'
:
self
.
assertRegex
(
v
,
'^(
\
*|<=?
\
d{4}|>=?
\
d{4})$'
,
'sublime_text must be `*` or of the form '
'<relation><version> '
'where <relation> is one of {<, <=, >, >=} '
'and <version> is a 4 digit number'
)
if
k
==
'platforms'
:
self
.
assertIsInstance
(
v
,
(
str_cls
,
list
))
elif
k
==
'tags'
:
self
.
assertTrue
(
bool
(
v
),
'"tags" must be `true` or a string of length>0'
)
if
isinstance
(
v
,
str_cls
):
v
=
[
v
]
for
plat
in
v
:
self
.
assertRegex
(
plat
,
r"^\*|(osx|linux|windows)(-x(32|64))?$"
)
self
.
assertFalse
(
v
==
"true"
,
'It is unlikely to specify the prefix '
'"true" use not the boolean `true`'
)
elif
k
==
'branch'
:
self
.
assertNotEqual
(
v
,
""
,
'"branch" must be non-empty'
)
elif
k
==
'sha256'
:
self
.
assertRegex
(
v
,
r'(?i)^[0-9a-f]{64}$'
)
def
enforce_key_types_map
(
self
,
k
,
v
,
key_types_map
):
self
.
assertIn
(
k
,
key_types_map
,
'Unknown key "
%
s"'
%
k
)
self
.
assertIsInstance
(
v
,
key_types_map
[
k
],
k
)
if
(
isinstance
(
v
,
list
)
and
key_types_map
[
k
]
!=
list
and
len
(
key_types_map
[
k
])
==
2
):
# Test if all of the lists elements are of the other allowed types
other_types
=
tuple
(
filter
(
lambda
t
:
t
!=
list
,
key_types_map
[
k
]))
for
sub_value
in
v
:
self
.
assertIsInstance
(
sub_value
,
other_types
,
k
)
def
_test_error
(
self
,
msg
,
e
=
None
):
"""
...
...
@@ -454,7 +460,7 @@ class TestContainer(object):
@
classmethod
def
_include_tests
(
cls
,
path
,
stream
):
"""
Return a tuple
of (method, args) to add to a unittest TestCase class.
Yields tuples
of (method, args) to add to a unittest TestCase class.
A meta-programming function to expand the definition of class at run
time, based on the contents of a file or URL.
...
...
@@ -474,7 +480,7 @@ class TestContainer(object):
success
=
False
try
:
if
re
.
match
(
'https?://'
,
path
,
re
.
I
)
is
not
None
:
if
re
.
match
(
r
'https?://'
,
path
,
re
.
I
)
is
not
None
:
# Download the repository
try
:
with
urlopen
(
path
)
as
f
:
...
...
@@ -539,7 +545,7 @@ class TestContainer(object):
for
release
in
package
[
'releases'
]:
(
yield
cls
.
_test_release
,
(
"
%
s (
%
s)"
%
(
package_name
,
path
),
release
,
False
))
release
,
False
,
False
))
if
'includes'
in
data
:
for
include
in
data
[
'includes'
]:
i_url
=
urljoin
(
path
,
include
)
...
...
@@ -643,7 +649,7 @@ class DefaultRepositoryTests(TestContainer, unittest.TestCase):
contents
=
f
.
read
()
.
decode
(
'utf-8'
,
'replace'
)
data
=
json
.
loads
(
contents
)
except
Exception
as
e
:
yield
cls
.
_
test_error
,
(
"Error while reading
%
r"
%
include
,
e
)
yield
cls
.
_
fail
(
"Error while reading
%
r"
%
include
,
e
)
continue
# `include` is for output during tests only
...
...
@@ -659,7 +665,9 @@ class DefaultRepositoryTests(TestContainer, unittest.TestCase):
if
'releases'
in
package
:
for
release
in
package
[
'releases'
]:
(
yield
cls
.
_test_release
,
(
"
%
s (
%
s)"
%
(
package_name
,
include
),
release
))
(
"
%
s (
%
s)"
%
(
package_name
,
include
),
release
,
False
))
if
'dependencies'
in
data
:
yield
cls
.
_test_dependency_order
,
(
include
,
data
)
...
...
@@ -671,9 +679,12 @@ class DefaultRepositoryTests(TestContainer, unittest.TestCase):
if
'releases'
in
dependency
:
for
release
in
dependency
[
'releases'
]:
(
yield
cls
.
_test_
dependency_
release
,
(
yield
cls
.
_test_release
,
(
"
%
s (
%
s)"
%
(
dependency_name
,
include
),
release
))
release
,
True
))
yield
cls
.
_fail
(
"This won't be executed for some reason"
)
def
generate_default_test_methods
(
stream
=
None
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment