Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: This adds a registry for both operators and arguments. This is necessary to provide a centralized place for clients to get arguments and operators specified in serialized switches. Test Plan: new tests Reviewers: kalail, NorthIsUp Reviewed By: NorthIsUp Differential Revision: http://phabricator.local.disqus.net/D12534
- Loading branch information
Showing
9 changed files
with
207 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
{ | ||
"project_id": "gutter", | ||
"copyright_holder": "Disqus, Inc.", | ||
"phutil_libraries": {"disqus": "/usr/local/include/php/libdisqus/src"}, | ||
"arcanist_configuration": "DisqusConfiguration", | ||
"conduit_uri": "http://phabricator.local.disqus.net/", | ||
"base": "git:merge-base(origin/master), arc:upstream, git:HEAD^", | ||
"differential.field-selector": "DisqusDifferentialFieldSelector", | ||
"history.immutable": false, | ||
"unit.engine": "GenericXUnitTestEngine", | ||
"unit.genericxunit.script": "make test-xunit XUNIT_FILE=arcanist.xml", | ||
"unit.genericxunit.result_path": "test_results/xunit" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"linters" : { | ||
"flake8" : { | ||
"type" : "flake8", | ||
"include" : "(\\.py$)", | ||
"exclude" : "(^.git/|^ci/|^env/|/vendor/|_pb2\\.py$)", | ||
"severity.rules" : { | ||
"(^(W292|W391))" : "disabled", | ||
"(^E501)" : "warning" | ||
} | ||
}, | ||
"filename" : { | ||
"type" : "filename", | ||
"include" : "(.*)" | ||
}, | ||
"text" : { | ||
"type" : "text", | ||
"include" : "(\\.txt$)" | ||
}, | ||
"nolint" : { | ||
"type" : "nolint", | ||
"include" : "(.*)" | ||
}, | ||
"generated" : { | ||
"type" : "generated", | ||
"include" : "(.*)" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ dist/ | |
docs/ | ||
build/ | ||
*.egg | ||
.arcconfig | ||
*.sublime-workspace | ||
.coverage | ||
test_results/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from gutter.client.operators import Base | ||
from gutter.client.arguments.base import Container | ||
|
||
|
||
class Registry(object): | ||
|
||
def __init__(self, cls): | ||
self.__items = {} | ||
self.__cls = cls | ||
|
||
items = property(lambda self: self.__items) | ||
|
||
def __getitem__(self, key): | ||
try: | ||
return self.__items[key] | ||
except KeyError: | ||
raise KeyError("Key '%s' not registered" % key) | ||
|
||
def register(self, key, obj): | ||
try: | ||
if not issubclass(obj, self.__cls): | ||
raise ValueError("%s is not a %s" % (obj, self.__cls)) | ||
except TypeError: | ||
raise ValueError("%s is not a %s" % (obj, self.__cls)) | ||
|
||
self.__items[key] = obj | ||
|
||
|
||
def extract_key_from_name(func): | ||
def helpful_register(key_or_operator=None, operator=None): | ||
if not operator: | ||
operator = key_or_operator | ||
key = operator.name | ||
else: | ||
key = key_or_operator | ||
|
||
return func(key, operator) | ||
|
||
return helpful_register | ||
|
||
|
||
arguments = Registry(Container) | ||
operators = Registry(Base) | ||
|
||
|
||
operators.register = extract_key_from_name(operators.register) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import itertools | ||
import unittest2 | ||
from copy import copy | ||
|
||
from exam.cases import Exam | ||
from exam.decorators import around | ||
|
||
from gutter.client.operators import ( | ||
Base, | ||
comparable, | ||
identity, | ||
misc, | ||
) | ||
from gutter.client.arguments.base import Container | ||
from gutter.client import registry | ||
|
||
def all_operators_in(module): | ||
for _, obj in vars(module).iteritems(): | ||
try: | ||
if issubclass(obj, Base) and obj is not Base: | ||
yield obj | ||
except TypeError: | ||
pass | ||
|
||
|
||
ALL_OPERATORS = itertools.chain( | ||
*map(all_operators_in, (comparable, identity, misc)) | ||
) | ||
|
||
|
||
class TestOperator(Base): | ||
name = 'test_name' | ||
|
||
|
||
class TestArgument(Container): | ||
pass | ||
|
||
|
||
class TestOperatorRegistry(Exam, unittest2.TestCase): | ||
|
||
@around | ||
def preserve_registry(self): | ||
original = registry.operators | ||
registry.operators = copy(registry.operators) | ||
yield | ||
registry.operators = original | ||
|
||
def test_has_default_operators_registered_by_default(self): | ||
for operator in ALL_OPERATORS: | ||
self.assertEqual(operator, registry.operators[operator.name]) | ||
|
||
def test_stores_registered_operator_via_provided_name(self): | ||
registry.operators.register('hello', TestOperator) | ||
self.assertEqual(registry.operators['hello'], TestOperator) | ||
|
||
def test_uses_operator_name_if_not_provided_one(self): | ||
registry.operators.register(TestOperator) | ||
self.assertEqual(registry.operators['test_name'], TestOperator) | ||
|
||
def test_raises_exception_if_object_is_not_an_operator(self): | ||
self.assertRaises( | ||
ValueError, | ||
registry.operators.register, | ||
'junk', | ||
'thing' | ||
) | ||
|
||
|
||
class TestArgumentRegistry(Exam, unittest2.TestCase): | ||
|
||
@around | ||
def preserve_registry(self): | ||
original = registry.arguments | ||
registry.arguments = copy(registry.arguments) | ||
yield | ||
registry.arguments = original | ||
|
||
def test_stores_registered_argument_via_provided_name(self): | ||
registry.arguments.register('test', TestArgument) | ||
self.assertEqual(registry.arguments['test'], TestArgument) | ||
|
||
def test_raises_exception_if_object_is_not_an_argument(self): | ||
self.assertRaises( | ||
ValueError, | ||
registry.arguments.register, | ||
'junk', | ||
'thing' | ||
) |