﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
29020	incomplete instructions in contributing tutorial	Artem Fedulov	nobody	"I go back to commit 4ccfc4439a7add24f8db4ef3960d02ef8ae09887
make sure that tests from test_forms.py passed.

I do all the modifications documentation requires in this section
 https://docs.djangoproject.com/en/2.0/intro/contributing/#verifying-your-test-now-passes:
Add tests for prefix field at tests/forms_tests/tests/test_forms.py:
{{{
def test_class_prefix(self):
    # Prefix can be also specified at the class level.
    class Person(Form):
        first_name = CharField()
        prefix = 'foo'

    p = Person()
    self.assertEqual(p.prefix, 'foo')

    p = Person(prefix='bar')
    self.assertEqual(p.prefix, 'bar')
}}}
Add prefix field to BaseForm at django/django/forms/forms.py and update BaseField`s {{{__init__}}} method to set prefix if provided:
{{{
class BaseForm:
    # This is the main implementation of all the Form logic. Note that this
    # class is different than Form. See the comments by the Form class for
    # more information. Any improvements to the form API should be made to
    # *this* class, not to the Form class.
    field_order = None
    prefix = None

def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=None,
                 empty_permitted=False, field_order=None):
        self.is_bound = data is not None or files is not None
        self.data = data or {}
        self.files = files or {}
        self.auto_id = auto_id
        if prefix is not None:
            self.prefix = prefix
        self.initial = initial or {}
        self.error_class = error_class
        # Translators: This is the default suffix added to form field labels
        self.label_suffix = label_suffix if label_suffix is not None else _(':')
        self.empty_permitted = empty_permitted
        self._errors = None  # Stores the errors after clean() has been called.
        self._changed_data = None

        # The base_fields class attribute is the *class-wide* definition of
        # fields. Because a particular *instance* of the class might want to
        # alter self.fields, we create self.fields here by copying base_fields.
        # Instances should always modify self.fields; they should not modify
        # self.base_fields.
        self.fields = copy.deepcopy(self.base_fields)
        self._bound_fields_cache = {}
        self.order_fields(self.field_order if field_order is None else field_order)
}}}


But the tests still fail, because the form is now created with a prefix.

{{{
FAIL: test_forms_with_null_boolean (forms_tests.tests.test_forms.FormsTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ""C:\Users\artem\Project_home\django\tests\forms_tests\tests\test_forms.
py"", line 1693, in test_forms_with_null_boolean
    </select>"""""")
  File ""c:\users\artem\project_home\django\django\test\testcases.py"", line 692
, in assertHTMLEqual
    self.fail(self._formatMessage(msg, standardMsg))
AssertionError: <select name=""foo-is_cool"">
<option selected=""selected"" value=""1"">
Unknown
</opt [truncated]... != <select name=""is_cool"">
<option selected=""selected"" value=""1"">
Unknown
</option> [truncated]...
- <select name=""foo-is_cool"">
?               ----

+ <select name=""is_cool"">
  <option selected=""selected"" value=""1"">
  Unknown
  </option><option value=""2"">
  Yes
  </option><option value=""3"">
  No
  </option>
  </select>
}}}
So we need another modification to test_forms.py file to get tests passed.

For example, check if field name now is prefixed with default value :
{{{
def test_forms_with_null_boolean(self):
        # NullBooleanField is a bit of a special case because its presentation (widget)
        # is different than its data. This is handled transparently, though.
        class Person(Form):
            name = CharField()
            is_cool = NullBooleanField()
            prefix = 'foo'

        p = Person()
        self.assertEqual(p.prefix, 'foo')

        p = Person(prefix='bar')
        self.assertEqual(p.prefix, 'bar')

        p = Person({'name': 'Joe'}, auto_id=False)
        self.assertHTMLEqual(str(p['is_cool']), """"""<select name=""foo-is_cool"">
<option value=""1"" selected=""selected"">Unknown</option>
<option value=""2"">Yes</option>
<option value=""3"">No</option>
</select>"""""")
        p = Person({'name': 'Joe', 'foo-is_cool': '1'}, auto_id=False)
        self.assertHTMLEqual(str(p['is_cool']), """"""<select name=""foo-is_cool"">
<option value=""1"" selected=""selected"">Unknown</option>
<option value=""2"">Yes</option>
<option value=""3"">No</option>
</select>"""""")
        p = Person({'name': 'Joe', 'foo-is_cool': '2'}, auto_id=False)
        self.assertHTMLEqual(str(p['is_cool']), """"""<select name=""foo-is_cool"">
<option value=""1"">Unknown</option>
<option value=""2"" selected=""selected"">Yes</option>
<option value=""3"">No</option>
</select>"""""")
        p = Person({'name': 'Joe', 'foo-is_cool': '3'}, auto_id=False)
        self.assertHTMLEqual(str(p['is_cool']), """"""<select name=""foo-is_cool"">
<option value=""1"">Unknown</option>
<option value=""2"">Yes</option>
<option value=""3"" selected=""selected"">No</option>
</select>"""""")
        p = Person({'name': 'Joe', 'foo-is_cool': True}, auto_id=False)
        self.assertHTMLEqual(str(p['is_cool']), """"""<select name=""foo-is_cool"">
<option value=""1"">Unknown</option>
<option value=""2"" selected=""selected"">Yes</option>
<option value=""3"">No</option>
</select>"""""")
        p = Person({'name': 'Joe', 'foo-is_cool': False}, auto_id=False)
        self.assertHTMLEqual(str(p['is_cool']), """"""<select name=""foo-is_cool"">
<option value=""1"">Unknown</option>
<option value=""2"">Yes</option>
<option value=""3"" selected=""selected"">No</option>
</select>"""""")
}}}"	Cleanup/optimization	closed	Documentation	2.0	Normal	invalid			Unreviewed	0	0	0	0	0	0
