)]}'
{"ironic/api/controllers/v1/types.py":[{"author":{"_account_id":6623,"name":"Roman Prykhodchenko","email":"me@romcheg.me","username":"prykhodchenko"},"change_message_id":"b14fb6bfe190a906e7122642574199bd9125e59f","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        return value"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"class PatchType(object):"},{"line_number":113,"context_line":"    \"\"\"Complex type to validate json-patches.\"\"\""},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    path \u003d wtypes.wsattr(StringType(pattern\u003d\u0027^(/[\\w-]+)+$\u0027), mandatory\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F918E%3D","line":112,"updated":"2013-12-05 10:50:15.000000000","message":"Shouldn\u0027t it be inherited from wtypes.UserType?","commit_id":"ca7f368908a8e0263e975a7b2be03b09588f411f"},{"author":{"_account_id":7308,"name":"Eugene Frolov","email":"efrolov@mirantis.com","username":"efrolov"},"change_message_id":"044b4f2811344d75d7962223d17ed6a9bafad197","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        return value"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"class PatchType(object):"},{"line_number":113,"context_line":"    \"\"\"Complex type to validate json-patches.\"\"\""},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    path \u003d wtypes.wsattr(StringType(pattern\u003d\u0027^(/[\\w-]+)+$\u0027), mandatory\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F91ig%3D","line":112,"in_reply_to":"AAAATn%2F918E%3D","updated":"2013-12-05 12:21:47.000000000","message":"I personally think that  answer on the question is \"no\"","commit_id":"ca7f368908a8e0263e975a7b2be03b09588f411f"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"22f7eca3643a081b2a498efb68ea5da93c1ce66d","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        return value"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"class PatchType(object):"},{"line_number":113,"context_line":"    \"\"\"Complex type to validate json-patches.\"\"\""},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    path \u003d wtypes.wsattr(StringType(pattern\u003d\u0027^(/[\\w-]+)+$\u0027), mandatory\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F91Q8%3D","line":112,"in_reply_to":"AAAATn%2F91Zc%3D","updated":"2013-12-05 13:34:49.000000000","message":"I also asked myself that but as I couldn\u0027t find a proper documentation about it on the WSME documentation I was using their code as an example, so if you look at their code some of the types are also no inherited from UserType[1]. Inheriting from UserType would add 2 more attributes to my class: name and basetype[2] which is a bit undesirable and won\u0027t be used (since we are not implementing frombasetype(), tobasetype() methods for this class)... But, I agree with u that it looks incosistent and inheriting from UserType won\u0027t do any harm to us (since we are ignoring the two extra attributes) so, I see more value on being consistent, I will submit a new patchset changing it.\n\nThanks for the suggestion\n\n[1] https://github.com/stackforge/wsme/blob/master/wsme/types.py#L32, https://github.com/stackforge/wsme/blob/master/wsme/types.py#L69, https://github.com/stackforge/wsme/blob/master/wsme/types.py#L766\n\n[2] https://github.com/stackforge/wsme/blob/master/wsme/types.py#L108-109","commit_id":"ca7f368908a8e0263e975a7b2be03b09588f411f"},{"author":{"_account_id":6623,"name":"Roman Prykhodchenko","email":"me@romcheg.me","username":"prykhodchenko"},"change_message_id":"c75b077a86b8858c468b52d6406fb311aee2f234","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        return value"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"class PatchType(object):"},{"line_number":113,"context_line":"    \"\"\"Complex type to validate json-patches.\"\"\""},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    path \u003d wtypes.wsattr(StringType(pattern\u003d\u0027^(/[\\w-]+)+$\u0027), mandatory\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F91Zc%3D","line":112,"in_reply_to":"AAAATn%2F91ig%3D","updated":"2013-12-05 13:05:41.000000000","message":"Eugene, can you please add more details because I don\u0027t think I follow you.","commit_id":"ca7f368908a8e0263e975a7b2be03b09588f411f"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"0fc6106a0811f44582d198d54173054a97b894ff","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        return []"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    @staticmethod"},{"line_number":135,"context_line":"    def sanitize_attrs(attrs):"},{"line_number":136,"context_line":"        return [attr if attr.startswith(\u0027/\u0027) else \u0027/\u0027 + attr"},{"line_number":137,"context_line":"                for attr in attrs]"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F9hO0%3D","line":135,"updated":"2013-12-10 16:58:58.000000000","message":"Instead of calling sanitize_attrs() every time validate() is called, I would prefer that it is called once -- ideally, when the class is created; alternately, when it is instantiated. The internal_attrs and mandatory_attrs are not going to change thereafter, so they do not need to be sanitized thereafter.","commit_id":"3e36e945a4e36d47ed27ec98d73b1e6a2ed500ec"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c69106455a766c912773d101228f979572e80d8","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        return []"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    @staticmethod"},{"line_number":135,"context_line":"    def sanitize_attrs(attrs):"},{"line_number":136,"context_line":"        return [attr if attr.startswith(\u0027/\u0027) else \u0027/\u0027 + attr"},{"line_number":137,"context_line":"                for attr in attrs]"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F9b7M%3D","line":135,"in_reply_to":"AAAATn%2F9hO0%3D","updated":"2013-12-11 17:52:08.000000000","message":"As talked on IRC, I\u0027ll remove the sanitize method, since as you rightly pointed out, the list of attributes doesn\u0027t change dynamically\n\n\u003clucasagomes\u003e as they are hardcoded (won\u0027t change) do we really need an sanitize method?\n\n\u003cdevananda\u003e lucasagomes: nope\n\n\u003clucasagomes\u003e devananda, right :)\n\n\u003cdevananda\u003e lucasagomes: that was my first thought. then i assumed you had put it there in case someone subclassed it and didn\u0027t follow the right pattern. but that\u0027s what unit tests are for, IMO.\n\n\u003cdevananda\u003e i think it\u0027s worth a check somewhere. but not in object\u0027s runtime path :)\n\n\u003clucasagomes\u003e cool yea\n\n\u003clucasagomes\u003e also because we don\u0027t instantiate that class ourself, it\u0027s done by wsme\n\n\u003clucasagomes\u003e so sanitizing on the constructor will have the same effect as sanitizing at the validate() method... the sanitize() will be called the same no of times\n\n\u003clucasagomes\u003e which is, everytime a request comes in\n\n\u003cdevananda\u003e right\n\n\u003cdevananda\u003e which seems very inefficient\n\n\u003clucasagomes\u003e yup","commit_id":"3e36e945a4e36d47ed27ec98d73b1e6a2ed500ec"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"0fc6106a0811f44582d198d54173054a97b894ff","unresolved":false,"context_lines":[{"line_number":143,"context_line":"            raise wsme.exc.ClientSideError(msg % patch.path)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        if patch.op \u003d\u003d \u0027remove\u0027 and \\"},{"line_number":146,"context_line":"                patch.path in cls.sanitize_attrs(cls.mandatory_attrs()):"},{"line_number":147,"context_line":"            msg \u003d _(\"\u0027%s\u0027 is a mandatory attribute and can not be removed\")"},{"line_number":148,"context_line":"            raise wsme.exc.ClientSideError(msg % patch.path)"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F9hSc%3D","line":146,"updated":"2013-12-10 16:58:58.000000000","message":"shouldn\u0027t this be:\n\n  if patch.op \u003d\u003d \u0027remove\u0027 and patch.path in \\\n      cls.sanitize_attrs(cls.mandatory_attrs() + cls.internal_attrs()):","commit_id":"3e36e945a4e36d47ed27ec98d73b1e6a2ed500ec"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"fcfe3cb48e3578719f4b0683b405a5a5e628ad03","unresolved":false,"context_lines":[{"line_number":143,"context_line":"            raise wsme.exc.ClientSideError(msg % patch.path)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        if patch.op \u003d\u003d \u0027remove\u0027 and \\"},{"line_number":146,"context_line":"                patch.path in cls.sanitize_attrs(cls.mandatory_attrs()):"},{"line_number":147,"context_line":"            msg \u003d _(\"\u0027%s\u0027 is a mandatory attribute and can not be removed\")"},{"line_number":148,"context_line":"            raise wsme.exc.ClientSideError(msg % patch.path)"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F9ayU%3D","line":146,"in_reply_to":"AAAATn%2F9cFI%3D","updated":"2013-12-11 18:23:53.000000000","message":"Ah, right you are.","commit_id":"3e36e945a4e36d47ed27ec98d73b1e6a2ed500ec"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c69106455a766c912773d101228f979572e80d8","unresolved":false,"context_lines":[{"line_number":143,"context_line":"            raise wsme.exc.ClientSideError(msg % patch.path)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        if patch.op \u003d\u003d \u0027remove\u0027 and \\"},{"line_number":146,"context_line":"                patch.path in cls.sanitize_attrs(cls.mandatory_attrs()):"},{"line_number":147,"context_line":"            msg \u003d _(\"\u0027%s\u0027 is a mandatory attribute and can not be removed\")"},{"line_number":148,"context_line":"            raise wsme.exc.ClientSideError(msg % patch.path)"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F9cFI%3D","line":146,"in_reply_to":"AAAATn%2F9hSc%3D","updated":"2013-12-11 17:52:08.000000000","message":"The first condition already prevent any internal attribute from being updated (add, replaced or removed)","commit_id":"3e36e945a4e36d47ed27ec98d73b1e6a2ed500ec"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"2ceff2f77130d6f6a0cf0ec8a35d9d4e84c03784","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        \"\"\""},{"line_number":132,"context_line":"        return [\u0027/created_at\u0027, \u0027/id\u0027, \u0027/links\u0027, \u0027/updated_at\u0027, \u0027/uuid\u0027]"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def mandatory_attrs(self):"},{"line_number":135,"context_line":"        \"\"\"Retruns a list of mandatory attributes."},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        Mandatory attributes can not be removed from the document. This"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATn%2F9aUM%3D","line":134,"updated":"2013-12-11 19:58:48.000000000","message":"I just reviewed the next patch in this series, and noticed that mandatory_attrs is no longer defined as a staticmethod. Why is that?\n\nWSME will be instantiating classes which inherit from this one, but those classes can still override the mandatory_attrs method. I don\u0027t see how the definition of internal_attrs should be any different, so I don\u0027t understand why one is static and the other is not.","commit_id":"6d181091dc28f5f6f04bd95dfd851586a592f586"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"9ee1b19f7fa0f4e74e57e0fa35db728dd3596ce3","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        \"\"\""},{"line_number":132,"context_line":"        return [\u0027/created_at\u0027, \u0027/id\u0027, \u0027/links\u0027, \u0027/updated_at\u0027, \u0027/uuid\u0027]"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def mandatory_attrs(self):"},{"line_number":135,"context_line":"        \"\"\"Retruns a list of mandatory attributes."},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        Mandatory attributes can not be removed from the document. This"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATn%2F9aB0%3D","line":134,"in_reply_to":"AAAATn%2F9aUM%3D","updated":"2013-12-11 20:54:17.000000000","message":"The reason why I defined internal_attrs as static was to be able to access the default internal attributes easily. For e.g: On Nodes apart from the defaults internal attributes (created_at, id, etc...) we have other attributes that can\u0027t be updated by the patch method: last_error, target_*_state, *_state. So having the internal_attrs as static on the base class I can do something like:\n\ndef internal_attrs(self):\n    defaults \u003d JsonPatchType.internal_attrs()\n    return defaults + [\u0027/last_error\u0027, ...]\n\nhttps://review.openstack.org/#/c/57495/20/ironic/api/controllers/v1/node.py\n\nMaybe it\u0027s not the best way to do it, will discuss it on IRC.","commit_id":"6d181091dc28f5f6f04bd95dfd851586a592f586"}],"ironic/tests/api/test_types.py":[{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                pass"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"        my_root \u003d MyRoot([\u0027restjson\u0027])"},{"line_number":75,"context_line":"        app \u003d webtest.TestApp(my_root.wsgiapp())"},{"line_number":76,"context_line":"        return app.patch_json(\u0027/test\u0027, params\u003dparams,"},{"line_number":77,"context_line":"                              headers\u003d{\u0027Accept\u0027: \u0027application/json\u0027},"},{"line_number":78,"context_line":"                              expect_errors\u003dexpect_errors)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9woI%3D","line":75,"updated":"2013-12-06 10:12:25.000000000","message":"Since this stuff is stateless maybe it would be better to create app only once in setUp()","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                pass"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"        my_root \u003d MyRoot([\u0027restjson\u0027])"},{"line_number":75,"context_line":"        app \u003d webtest.TestApp(my_root.wsgiapp())"},{"line_number":76,"context_line":"        return app.patch_json(\u0027/test\u0027, params\u003dparams,"},{"line_number":77,"context_line":"                              headers\u003d{\u0027Accept\u0027: \u0027application/json\u0027},"},{"line_number":78,"context_line":"                              expect_errors\u003dexpect_errors)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wOs%3D","line":75,"in_reply_to":"AAAATn%2F9woI%3D","updated":"2013-12-06 11:46:12.000000000","message":"+1 will use the fixtures for it :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                         {\u0027path\u0027: \u0027/extra/foo\u0027, \u0027op\u0027: \u0027add\u0027, \u0027value\u0027: \u0027bar\u0027},"},{"line_number":83,"context_line":"                         {\u0027path\u0027: \u0027/foo\u0027, \u0027op\u0027: \u0027replace\u0027, \u0027value\u0027: \u0027bar\u0027}]"},{"line_number":84,"context_line":"        ret \u003d self._patch_json(valid_patches, False)"},{"line_number":85,"context_line":"        self.assertEqual(ret.status_int, 200)"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def test_internal_attr(self):"},{"line_number":88,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/internal\u0027, \u0027op\u0027: \u0027replace\u0027, \u0027value\u0027: \u0027foo\u0027}]"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wow%3D","line":85,"updated":"2013-12-06 10:12:25.000000000","message":"A boring comment about assertEqual(self, expected, observed... Sorry! \u003d)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                         {\u0027path\u0027: \u0027/extra/foo\u0027, \u0027op\u0027: \u0027add\u0027, \u0027value\u0027: \u0027bar\u0027},"},{"line_number":83,"context_line":"                         {\u0027path\u0027: \u0027/foo\u0027, \u0027op\u0027: \u0027replace\u0027, \u0027value\u0027: \u0027bar\u0027}]"},{"line_number":84,"context_line":"        ret \u003d self._patch_json(valid_patches, False)"},{"line_number":85,"context_line":"        self.assertEqual(ret.status_int, 200)"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def test_internal_attr(self):"},{"line_number":88,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/internal\u0027, \u0027op\u0027: \u0027replace\u0027, \u0027value\u0027: \u0027foo\u0027}]"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wO4%3D","line":85,"in_reply_to":"AAAATn%2F9wow%3D","updated":"2013-12-06 11:46:12.000000000","message":"heh no problem will fix it :D","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        ret \u003d self._patch_json(valid_patches, False)"},{"line_number":85,"context_line":"        self.assertEqual(ret.status_int, 200)"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def test_internal_attr(self):"},{"line_number":88,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/internal\u0027, \u0027op\u0027: \u0027replace\u0027, \u0027value\u0027: \u0027foo\u0027}]"},{"line_number":89,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":90,"context_line":"        self.assertEqual(ret.status_int, 400)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wmk%3D","line":87,"updated":"2013-12-06 10:12:25.000000000","message":"I suggest test_cannot_update_internal_attr","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        ret \u003d self._patch_json(valid_patches, False)"},{"line_number":85,"context_line":"        self.assertEqual(ret.status_int, 200)"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def test_internal_attr(self):"},{"line_number":88,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/internal\u0027, \u0027op\u0027: \u0027replace\u0027, \u0027value\u0027: \u0027foo\u0027}]"},{"line_number":89,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":90,"context_line":"        self.assertEqual(ret.status_int, 400)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wPA%3D","line":87,"in_reply_to":"AAAATn%2F9wmk%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":90,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def test_mandatory_attr(self):"},{"line_number":93,"context_line":"        patch \u003d [{\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/mandatory\u0027, \u0027value\u0027: \u0027foo\u0027}]"},{"line_number":94,"context_line":"        ret \u003d self._patch_json(patch, False)"},{"line_number":95,"context_line":"        self.assertEqual(ret.status_int, 200)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wmc%3D","line":92,"updated":"2013-12-06 10:12:25.000000000","message":"test_replace_mandatory_attr","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":90,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def test_mandatory_attr(self):"},{"line_number":93,"context_line":"        patch \u003d [{\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/mandatory\u0027, \u0027value\u0027: \u0027foo\u0027}]"},{"line_number":94,"context_line":"        ret \u003d self._patch_json(patch, False)"},{"line_number":95,"context_line":"        self.assertEqual(ret.status_int, 200)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wPI%3D","line":92,"in_reply_to":"AAAATn%2F9wmc%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        ret \u003d self._patch_json(patch, False)"},{"line_number":95,"context_line":"        self.assertEqual(ret.status_int, 200)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        # mandatory attrs can\u0027t be removed"},{"line_number":98,"context_line":"        patch \u003d [{\u0027op\u0027: \u0027remove\u0027, \u0027path\u0027: \u0027/mandatory\u0027}]"},{"line_number":99,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":100,"context_line":"        self.assertEqual(ret.status_int, 400)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wmI%3D","line":97,"updated":"2013-12-06 10:12:25.000000000","message":"A separate test test_cannot_remove_mandatory_attr\n\nFYI a good pattern to follow http://c2.com/cgi/wiki?ArrangeActAssert . It\u0027s clearly seen that here we have two sets of \u0027AAA\u0027 \u003d)\n\nMy general point against multiple \"goals\" in one test is that when the first one fails the next ones are not executed. It\u0027s kinda skipping tests. Yea it tells you that something is broken, but doesn\u0027t give a full picture","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        ret \u003d self._patch_json(patch, False)"},{"line_number":95,"context_line":"        self.assertEqual(ret.status_int, 200)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        # mandatory attrs can\u0027t be removed"},{"line_number":98,"context_line":"        patch \u003d [{\u0027op\u0027: \u0027remove\u0027, \u0027path\u0027: \u0027/mandatory\u0027}]"},{"line_number":99,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":100,"context_line":"        self.assertEqual(ret.status_int, 400)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wOY%3D","line":97,"in_reply_to":"AAAATn%2F9wds%3D","updated":"2013-12-06 11:46:12.000000000","message":"Good stuff! I\u0027m a disaster with tests heh. Thank you for pointing that out, I agree with that and will pay more attention of the future tests to do it right","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"d9de930a4384c193d4d84149017cbe9c156c2f00","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        ret \u003d self._patch_json(patch, False)"},{"line_number":95,"context_line":"        self.assertEqual(ret.status_int, 200)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        # mandatory attrs can\u0027t be removed"},{"line_number":98,"context_line":"        patch \u003d [{\u0027op\u0027: \u0027remove\u0027, \u0027path\u0027: \u0027/mandatory\u0027}]"},{"line_number":99,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":100,"context_line":"        self.assertEqual(ret.status_int, 400)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wds%3D","line":97,"in_reply_to":"AAAATn%2F9wmI%3D","updated":"2013-12-06 10:19:22.000000000","message":"*As for AAA - I don\u0027t think we need to split them by an empty lines if each A is only one line \u003d)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":100,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def test_missing_required_fields(self):"},{"line_number":103,"context_line":"        missing_path \u003d [{\u0027op\u0027: \u0027remove\u0027}]"},{"line_number":104,"context_line":"        ret \u003d self._patch_json(missing_path, True)"},{"line_number":105,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":106,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wmA%3D","line":103,"updated":"2013-12-06 10:12:25.000000000","message":"Separate test_missing_required_fields_path","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":100,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def test_missing_required_fields(self):"},{"line_number":103,"context_line":"        missing_path \u003d [{\u0027op\u0027: \u0027remove\u0027}]"},{"line_number":104,"context_line":"        ret \u003d self._patch_json(missing_path, True)"},{"line_number":105,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":106,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wOM%3D","line":103,"in_reply_to":"AAAATn%2F9wmA%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        ret \u003d self._patch_json(missing_path, True)"},{"line_number":105,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        missing_op \u003d [{\u0027path\u0027: \u0027/foo\u0027}]"},{"line_number":108,"context_line":"        ret \u003d self._patch_json(missing_op, True)"},{"line_number":109,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":110,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wl8%3D","line":107,"updated":"2013-12-06 10:12:25.000000000","message":"Separate test_missing_required_fields_op","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        ret \u003d self._patch_json(missing_path, True)"},{"line_number":105,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        missing_op \u003d [{\u0027path\u0027: \u0027/foo\u0027}]"},{"line_number":108,"context_line":"        ret \u003d self._patch_json(missing_op, True)"},{"line_number":109,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":110,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wOQ%3D","line":107,"in_reply_to":"AAAATn%2F9wl8%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":119,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def test_add_to_root(self):"},{"line_number":122,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/foo\u0027, \u0027op\u0027: \u0027add\u0027, \u0027value\u0027: \u0027bar\u0027}]"},{"line_number":123,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":124,"context_line":"        self.assertEqual(ret.status_int, 400)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wl0%3D","line":121,"updated":"2013-12-06 10:12:25.000000000","message":"test_cannot_add_to_root","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":119,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def test_add_to_root(self):"},{"line_number":122,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/foo\u0027, \u0027op\u0027: \u0027add\u0027, \u0027value\u0027: \u0027bar\u0027}]"},{"line_number":123,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":124,"context_line":"        self.assertEqual(ret.status_int, 400)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wOI%3D","line":121,"in_reply_to":"AAAATn%2F9wl0%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    def test_add_replace_with_no_value(self):"},{"line_number":127,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/extra/foo\u0027, \u0027op\u0027: \u0027add\u0027}]"},{"line_number":128,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":129,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":130,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wlo%3D","line":127,"updated":"2013-12-06 10:12:25.000000000","message":"test_cannot_add_with_no_value","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    def test_add_replace_with_no_value(self):"},{"line_number":127,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/extra/foo\u0027, \u0027op\u0027: \u0027add\u0027}]"},{"line_number":128,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":129,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":130,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wOA%3D","line":127,"in_reply_to":"AAAATn%2F9wlo%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":129,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/foo\u0027, \u0027op\u0027: \u0027replace\u0027}]"},{"line_number":132,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":133,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":134,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wlk%3D","line":131,"updated":"2013-12-06 10:12:25.000000000","message":"test_cannot_replace_with_no_value","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":129,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"        patch \u003d [{\u0027path\u0027: \u0027/foo\u0027, \u0027op\u0027: \u0027replace\u0027}]"},{"line_number":132,"context_line":"        ret \u003d self._patch_json(patch, True)"},{"line_number":133,"context_line":"        self.assertEqual(ret.status_int, 400)"},{"line_number":134,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wN8%3D","line":131,"in_reply_to":"AAAATn%2F9wlk%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":140,"context_line":"                             pattern\u003d\u0027^[a-zA-Z0-9]*$\u0027)"},{"line_number":141,"context_line":"        v.validate(\u00271\u0027)"},{"line_number":142,"context_line":"        v.validate(\u002712345\u0027)"},{"line_number":143,"context_line":"        v.validate(\u00271234567890\u0027)"},{"line_number":144,"context_line":"        v.validate(\u0027aAbBcCzZ\u0027)"},{"line_number":145,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027\u0027)"},{"line_number":146,"context_line":"        self.assertRaises(ValueError, v.validate, \u002712345678901\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wfs%3D","line":143,"updated":"2013-12-06 10:12:25.000000000","message":"v.validate(\u0027x\u0027 * 10) is more clear IMO","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":140,"context_line":"                             pattern\u003d\u0027^[a-zA-Z0-9]*$\u0027)"},{"line_number":141,"context_line":"        v.validate(\u00271\u0027)"},{"line_number":142,"context_line":"        v.validate(\u002712345\u0027)"},{"line_number":143,"context_line":"        v.validate(\u00271234567890\u0027)"},{"line_number":144,"context_line":"        v.validate(\u0027aAbBcCzZ\u0027)"},{"line_number":145,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027\u0027)"},{"line_number":146,"context_line":"        self.assertRaises(ValueError, v.validate, \u002712345678901\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wN4%3D","line":143,"in_reply_to":"AAAATn%2F9wfs%3D","updated":"2013-12-06 11:46:12.000000000","message":"Indeed, done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":143,"context_line":"        v.validate(\u00271234567890\u0027)"},{"line_number":144,"context_line":"        v.validate(\u0027aAbBcCzZ\u0027)"},{"line_number":145,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027\u0027)"},{"line_number":146,"context_line":"        self.assertRaises(ValueError, v.validate, \u002712345678901\u0027)"},{"line_number":147,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027_\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wfg%3D","line":146,"updated":"2013-12-06 10:12:25.000000000","message":"ditto \u0027x\u0027 * 11","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":143,"context_line":"        v.validate(\u00271234567890\u0027)"},{"line_number":144,"context_line":"        v.validate(\u0027aAbBcCzZ\u0027)"},{"line_number":145,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027\u0027)"},{"line_number":146,"context_line":"        self.assertRaises(ValueError, v.validate, \u002712345678901\u0027)"},{"line_number":147,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027_\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wNs%3D","line":146,"in_reply_to":"AAAATn%2F9wfg%3D","updated":"2013-12-06 11:46:12.000000000","message":"done :)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":8968,"name":"Max Lobur","email":"max_lobur@outlook.com","username":"max_lobur"},"change_message_id":"8a809bc6e2849e3aefcc3f4be8fd7404c1fd9d87","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        v.validate(\u0027aAbBcCzZ\u0027)"},{"line_number":145,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027\u0027)"},{"line_number":146,"context_line":"        self.assertRaises(ValueError, v.validate, \u002712345678901\u0027)"},{"line_number":147,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027_\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wfU%3D","line":147,"updated":"2013-12-06 10:12:25.000000000","message":"Wanted to say \u0027ditto\u0027 regarding multiple goals here but since we\u0027re expecting to switch to wsme\u0027s implementation I think it\u0027s OK. Also it\u0027s very easy to read \u003d)","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"c60d18fa2a237a08dd2458d43b4a0a2e28660eb4","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        v.validate(\u0027aAbBcCzZ\u0027)"},{"line_number":145,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027\u0027)"},{"line_number":146,"context_line":"        self.assertRaises(ValueError, v.validate, \u002712345678901\u0027)"},{"line_number":147,"context_line":"        self.assertRaises(ValueError, v.validate, \u0027_\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9wNI%3D","line":147,"in_reply_to":"AAAATn%2F9wfU%3D","updated":"2013-12-06 11:46:12.000000000","message":"Heh yea, the StringType class and this tests are going to be removed from here on the next WSME release, but I\u0027m going to try to improve this tests a bit more anyway :)\n\nThanks","commit_id":"1c0a6c22aa165d6ca44ddf92c7e6529e0b7699fe"},{"author":{"_account_id":7308,"name":"Eugene Frolov","email":"efrolov@mirantis.com","username":"efrolov"},"change_message_id":"0083e247e0637be171e596343c1868451a781ed2","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def setUp(self):"},{"line_number":110,"context_line":"        super(TestPatchType, self).setUp()"},{"line_number":111,"context_line":"        self.app \u003d webtest.TestApp(MyRoot([\u0027restjson\u0027]).wsgiapp())"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def _patch_json(self, params, expect_errors\u003dFalse):"},{"line_number":114,"context_line":"        return self.app.patch_json(\u0027/test\u0027, params\u003dparams,"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F9heY%3D","line":111,"updated":"2013-12-10 16:16:37.000000000","message":"I think that it is better to test PatchType class directly, without webtest. Like TestStringType in https://review.openstack.org/#/c/60798/1/ironic/tests/api/test_types.py","commit_id":"3e36e945a4e36d47ed27ec98d73b1e6a2ed500ec"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c69106455a766c912773d101228f979572e80d8","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def setUp(self):"},{"line_number":110,"context_line":"        super(TestPatchType, self).setUp()"},{"line_number":111,"context_line":"        self.app \u003d webtest.TestApp(MyRoot([\u0027restjson\u0027]).wsgiapp())"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def _patch_json(self, params, expect_errors\u003dFalse):"},{"line_number":114,"context_line":"        return self.app.patch_json(\u0027/test\u0027, params\u003dparams,"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAATn%2F9cD0%3D","line":111,"in_reply_to":"AAAATn%2F9heY%3D","updated":"2013-12-11 17:52:08.000000000","message":"I need webtest for some of the tests, e.g test_missing_required_fields_path() where I make use of the wsattr(..., mandatory\u003dTrue) to validate if the mandatory fields has been supplied. Notice that the validate method doesn\u0027t check whether those fields are present or not it rely on wsme to check that for us.\n\nThe StringType and PatchType are different, the PatchType is an API-type object (like Nodes/Port/Chassis), it doesn\u0027t have basetype/name attributes or methods like frombasetype()/tobasetype() like wsme.UserType types[1]\n\nIt\u0027s important to note that for some tests I could instantiate the class directly and test it like the StringType, but it doesn\u0027t sounds correct to test an type like the PatchType that rely on WSME for sme stuff. Also having webtest allows me to check if the correct return code is being returned after the test fails.\n\n\n[1] I did it wrong inheriting it from UserType after this comment: https://review.openstack.org/#/c/60194/1/ironic/api/controllers/v1/types.py\n\n[2] https://github.com/stackforge/wsme/blob/master/wsme/types.py","commit_id":"3e36e945a4e36d47ed27ec98d73b1e6a2ed500ec"}]}
