Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fixed #27546 -- Replaced hardcoded class names in misc. __repr__() methods. #7629

Merged
merged 2 commits into from
Dec 1, 2016

Conversation

Keda87
Copy link
Contributor

@Keda87 Keda87 commented Nov 29, 2016

@atombrella
Copy link
Contributor

Please reference the ticket number in the commit message. "Fixed #27546 -- ...".

I noticed BaseConverter does not have a test for repr (tests/utils_tests/test_baseconv.py). And for TranslateFile there aren't any tests. For serialization/deserialization, the tests are a bit odd for me.

def test_repr(self):
     base7 = BaseConverter('cjdhel3', sign='g')
     self.assertEqual(repr(base7), '<BaseConverter: base7 (cjdhel3)>')

@Keda87
Copy link
Contributor Author

Keda87 commented Nov 29, 2016

@atombrella where I can get convention documentation to write unit testing? I didn't find any in this link https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/
I want to add unit test TranslatableFile class but I avoid to create duplicate file.
also where is test file for serialization/deserialization?

Sorry, it is my first attempt to contribute in django.

Copy link
Member

@timgraham timgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try grepping in the tests directory to find places for the tests. e.g. searching for "makemessages" points to tests/i18n. If you can't find a good place for a particular class, let me know.

@@ -46,7 +46,8 @@ def __init__(self, dirpath, file_name, locale_dir):
self.locale_dir = locale_dir

def __repr__(self):
return "<TranslatableFile: %s>" % os.sep.join([self.dirpath, self.file])
return "<%s: %s>" % (self.__class__.__name__,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We allow lines up to 119 characters if it helps readability, or we use hanging indent like this:

return "<%s: %s>" % (
    self.__class__.__name__,
    ...,
)

@Keda87
Copy link
Contributor Author

Keda87 commented Nov 29, 2016

@timgraham I've search using makemessages keyword and found testing file under tests/i18n/test_extraction.py
should I create new class in that file? or I should create testing for TranslatableFile in a new file under tests/i18n?

@timgraham
Copy link
Member

I think i18n/test_management.py would be fine.

Copy link
Member

@timgraham timgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you confirm that all the changes are tested?

return "<DeserializedObject: %s(pk=%s)>" % (
self.object._meta.label, self.object.pk)
return "<%s: %s(pk=%s)>" % (self.__class__.__name__,
self.object._meta.label, self.object.pk)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about indentation applies throughout the PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen tests for this change. I think adding one (whether it's accurate):

    def test_deserialized_repr(self):
        AuthorProfile.objects.create(author=self.joe, date_of_birth=datetime(1970, 1, 1))
        serial_str = serializers.serialize(self.serializer_name, AuthorProfile.objects.all())
        self.assertFalse(self._get_field_values(serial_str, 'author'))

        for obj in serializers.deserialize(self.serializer_name, serial_str):
            self.assertEqual(repr(obj), '<DeserializedObject: AuthorProfile (pk=%s>' % obj.object.pk)

in tests/serializers/tests.py. I don't spot anything else than should be tested.

@Keda87
Copy link
Contributor Author

Keda87 commented Nov 30, 2016

Yes I do, I've test by running python tests/runtests.py -v 3 --keepdb

@timgraham
Copy link
Member

Sorry, I meant are there tests for all the affected _repr__() methods? You can check the coverage report.

@Keda87
Copy link
Contributor Author

Keda87 commented Nov 30, 2016

Ohh ya, some of them I haven't create test. I have check the coverage report, but why the report shows the old version code, rather than my changes?

@timgraham
Copy link
Member

The coverage report runs against master. There isn't any coverage reports for pull requests but it should be easy enough to write the tests without it.

@Keda87
Copy link
Contributor Author

Keda87 commented Nov 30, 2016

I have added more test

Copy link
Member

@timgraham timgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please split this into two commits: one that adds the tests and one that makes the changes to fix the ticket.

@@ -348,6 +348,18 @@ def test_serialize_proxy_model(self):
self.assertEqual(base_data, proxy_data.replace('proxy', ''))
self.assertEqual(base_data, proxy_proxy_data.replace('proxy', ''))

def test_deserialized_object_class_repr(self):
author = Author.objects.create(name='John Doe')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems too complicated, do you really need 3 models? Can you use an in-memory model with its pk set to make the test a bit faster? You could also avoid the need for string interpolation in the expected value if you initialize the model with a pk.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh ya, I don't need 3 models. Previously I thought the m2m_data param is required.
I haven't heard in memory model, is it okay if I only use author model??
I used string interpolation because I don't know the id from newly created model.

from django.core.management.commands.makemessages import TranslatableFile


class ManagementTest(TestCase):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test -> Tests

@@ -0,0 +1,14 @@
import os
from unittest import TestCase
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use django.test.SimpleTestCase

self.object._meta.label, self.object.pk)
return "<%s: %s(pk=%s)>" % (
self.__class__.__name__,
self.object._meta.label, self.object.pk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put self.object.pk on the next line include a trailing comma

return "<TranslatableFile: %s>" % os.sep.join([self.dirpath, self.file])
return "<%s: %s>" % (
self.__class__.__name__,
os.sep.join([self.dirpath, self.file])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add trailing comma

@@ -588,7 +588,10 @@ def get_index_by_name(self, name):
raise ValueError("No index named %s on model %s" % (name, self.name))

def __repr__(self):
return "<ModelState: '%s.%s'>" % (self.app_label, self.name)
return "<%s: '%s.%s'>" % (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single line looks okay here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do I need add trailing comma?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for a single line, the idea is to add one for things like multi-line dicts/tuples so that if more lines are added later, we don't have to modify the last line and add a comma.

@@ -90,6 +92,12 @@ def assertAnnotations(self, results, expected_annotations):
self.assertTrue(hasattr(result, annotation))
self.assertEqual(getattr(result, annotation), value)

def test_raw_query_class_repr(self):
query = 'SELECT * FROM raw_query_author'
raw_queryset_instance = RawQuerySet(raw_query=query)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raw_queryset_instance -> queryset

@timgraham timgraham changed the title Fixed #27546 -- Replace hardcoded class names in __repr__-methods Fixed #27546 -- Replaced hardcoded class names in misc. __repr__() methods. Nov 30, 2016
@timgraham
Copy link
Member

Looks better. Can you please split the commits as I suggested?

return "<DeserializedObject: %s(pk=%s)>" % (
self.object._meta.label, self.object.pk)
return "<%s: %s(pk=%s)>" % (self.__class__.__name__,
self.object._meta.label, self.object.pk)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen tests for this change. I think adding one (whether it's accurate):

    def test_deserialized_repr(self):
        AuthorProfile.objects.create(author=self.joe, date_of_birth=datetime(1970, 1, 1))
        serial_str = serializers.serialize(self.serializer_name, AuthorProfile.objects.all())
        self.assertFalse(self._get_field_values(serial_str, 'author'))

        for obj in serializers.deserialize(self.serializer_name, serial_str):
            self.assertEqual(repr(obj), '<DeserializedObject: AuthorProfile (pk=%s>' % obj.object.pk)

in tests/serializers/tests.py. I don't spot anything else than should be tested.

@Keda87
Copy link
Contributor Author

Keda87 commented Nov 30, 2016

@timgraham sorry out of topic, how to split my commit? I already pushed several commit.

@timgraham
Copy link
Member

You can:

  1. squash the existing commits
  2. git diff HEAD^1 django/ > ~/a.diff to export the changes in django/ to a diff.
  3. git checkout HEAD~1 django/ && git commit -a --amend to remove the changes in Django from the first commit.
  4. patch -p1 -i ~/a.diff to reapply changes from the diff
  5. git commit -a to create a second commit with the changes in django/
  6. Force push to your branch with the new commits.

@Keda87
Copy link
Contributor Author

Keda87 commented Dec 1, 2016

I cannot split it into two commits. I'm only make it in one commit.
I'm rebasing all my commits using g rebase -i HEAD~9 then I squash commit 2-9 and all commit merged in my first commit.

[update]
I've splitted into 2 commits 😁

@Keda87
Copy link
Contributor Author

Keda87 commented Dec 1, 2016

@timgraham I saw that some of my test didn't pass CI build because hardcoded ID on the expected result. should I use string interpolation again?

@timgraham
Copy link
Member

I updated the test to use an in-memory model as I suggested earlier. I think this should be good now, I'll just run the tests once more to confirm all is well.

@Keda87
Copy link
Contributor Author

Keda87 commented Dec 1, 2016

ahh TIL, I just know this trick. thanks!

@timgraham timgraham merged commit 48826aa into django:master Dec 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants