# Path: djng/forms/angular_base.py
# class NgBoundField(BoundField):
#     @property
#     def errors(self):
#         """
#         Returns a TupleErrorList for this field. This overloaded method adds additional error lists
#         to the errors as detected by the form validator.
#         """
#         if not hasattr(self, '_errors_cache'):
#             self._errors_cache = self.form.get_field_errors(self)
#         return self._errors_cache
# 
#     def css_classes(self, extra_classes=None):
#         """
#         Returns a string of space-separated CSS classes for the wrapping element of this input field.
#         """
#         if hasattr(extra_classes, 'split'):
#             extra_classes = extra_classes.split()
#         extra_classes = set(extra_classes or [])
#         # field_css_classes is an optional member of a Form optimized for django-angular
#         field_css_classes = getattr(self.form, 'field_css_classes', None)
#         if hasattr(field_css_classes, 'split'):
#             extra_classes.update(field_css_classes.split())
#         elif isinstance(field_css_classes, (list, tuple)):
#             extra_classes.update(field_css_classes)
#         elif isinstance(field_css_classes, dict):
#             extra_field_classes = []
#             for key in ('*', self.name):
#                 css_classes = field_css_classes.get(key)
#                 if hasattr(css_classes, 'split'):
#                     extra_field_classes = css_classes.split()
#                 elif isinstance(css_classes, (list, tuple)):
#                     if '__default__' in css_classes:
#                         css_classes.remove('__default__')
#                         extra_field_classes.extend(css_classes)
#                     else:
#                         extra_field_classes = css_classes
#             extra_classes.update(extra_field_classes)
#         return super(NgBoundField, self).css_classes(extra_classes)
# 
#     def as_widget(self, widget=None, attrs=None, only_initial=False):
#         """
#         Renders the field.
#         """
#         if not widget:
#             widget = self.field.widget
# 
#         # so that we can refer to the field when building the rendering context
#         widget._field = self.field
#         # Make sure that NgWidgetMixin is not already part of the widget's bases so it doesn't get added twice.
#         if not isinstance(widget, NgWidgetMixin):
#             widget.__class__ = type(widget.__class__.__name__, (NgWidgetMixin, widget.__class__), {})
#         return super(NgBoundField, self).as_widget(widget, attrs, only_initial)
# 
#     def build_widget_attrs(self, attrs, widget=None):
#         if not widget:
#             widget = self.field.widget
#         attrs = super(NgBoundField, self).build_widget_attrs(attrs, widget=widget)
#         if callable(getattr(self.field, 'update_widget_attrs', None)):
#             self.field.update_widget_attrs(self, attrs)
#         return attrs
# 
#     def label_tag(self, contents=None, attrs=None, label_suffix=None):
#         if self.field.render_label is False:
#             return ''  # label shall be rendered by the widget
#         attrs = attrs or {}
#         css_classes = getattr(self.field, 'label_css_classes', None)
#         if hasattr(css_classes, 'split'):
#             css_classes = css_classes.split()
#         css_classes = set(css_classes or [])
#         label_css_classes = getattr(self.form, 'label_css_classes', None)
#         if hasattr(label_css_classes, 'split'):
#             css_classes.update(label_css_classes.split())
#         elif isinstance(label_css_classes, (list, tuple)):
#             css_classes.update(label_css_classes)
#         elif isinstance(label_css_classes, dict):
#             for key in (self.name, '*',):
#                 extra_label_classes = label_css_classes.get(key)
#                 if hasattr(extra_label_classes, 'split'):
#                     extra_label_classes = extra_label_classes.split()
#                 extra_label_classes = set(extra_label_classes or [])
#                 css_classes.update(extra_label_classes)
#         if css_classes:
#             attrs.update({'class': ' '.join(css_classes)})
#         return super(NgBoundField, self).label_tag(contents, attrs, label_suffix='')


from base64 import b64encode
from django import VERSION
from django.test import TestCase
from pyquery.pyquery import PyQuery
from server.forms.client_validation import SubscribeForm as ClientValidatedForm
from server.forms.combined_validation import SubscribeForm as CombinedValidatedForm
from djng.forms.angular_base import NgBoundField
import six
    def test_ng_length(self):
        first_name = self.dom('input[name=first_name]')
        self.assertEqual(len(first_name), 1)
        attrib = dict(first_name[0].attrib.items())
        self.assertDictContainsSubset({'ng-required': 'true'}, attrib)
        self.assertDictContainsSubset({'ng-minlength': '3'}, attrib)
        self.assertDictContainsSubset({'ng-maxlength': '20'}, attrib)
        lis = self.dom('label[for=id_first_name]').closest('th').next('td').children('ul.djng-field-errors > li')
        if VERSION[1] == 5:
            # Django < 1.6 not not know about minlength and maxlength
            self.assertEqual(len(lis), 2)
        else:
            self.assertEqual(len(lis), 4)
        attrib = dict(lis[0].attrib.items())
        self.assertDictContainsSubset({'ng-show': self.form_name + six.u('[\'first_name\'].$error.required')}, attrib)
        attrib = dict(lis[1].attrib.items())
        self.assertDictContainsSubset({'ng-show': self.form_name + six.u('[\'first_name\'].$error.minlength')}, attrib)

    def test_type(self):
        email_field = self.dom('input[name=email]')
        self.assertEqual(len(email_field), 1)
        attrib = dict(email_field[0].attrib.items())
        self.assertNotIn('required', attrib)
        self.assertDictContainsSubset({'ng-model': 'email'}, attrib)
        if VERSION[1] == 5:
            self.assertDictContainsSubset({'type': 'text'}, attrib)
        else:
            self.assertDictContainsSubset({'type': 'email'}, attrib)

    def test_regex(self):

# Path: djng/forms/angular_base.py
# class NgBoundField(BoundField):
#     @property
#     def errors(self):
#         """
#         Returns a TupleErrorList for this field. This overloaded method adds additional error lists
#         to the errors as detected by the form validator.
#         """
#         if not hasattr(self, '_errors_cache'):
#             self._errors_cache = self.form.get_field_errors(self)
#         return self._errors_cache
# 
#     def css_classes(self, extra_classes=None):
#         """
#         Returns a string of space-separated CSS classes for the wrapping element of this input field.
#         """
#         if hasattr(extra_classes, 'split'):
#             extra_classes = extra_classes.split()
#         extra_classes = set(extra_classes or [])
#         # field_css_classes is an optional member of a Form optimized for django-angular
#         field_css_classes = getattr(self.form, 'field_css_classes', None)
#         if hasattr(field_css_classes, 'split'):
#             extra_classes.update(field_css_classes.split())
#         elif isinstance(field_css_classes, (list, tuple)):
#             extra_classes.update(field_css_classes)
#         elif isinstance(field_css_classes, dict):
#             extra_field_classes = []
#             for key in ('*', self.name):
#                 css_classes = field_css_classes.get(key)
#                 if hasattr(css_classes, 'split'):
#                     extra_field_classes = css_classes.split()
#                 elif isinstance(css_classes, (list, tuple)):
#                     if '__default__' in css_classes:
#                         css_classes.remove('__default__')
#                         extra_field_classes.extend(css_classes)
#                     else:
#                         extra_field_classes = css_classes
#             extra_classes.update(extra_field_classes)
#         return super(NgBoundField, self).css_classes(extra_classes)
# 
#     def as_widget(self, widget=None, attrs=None, only_initial=False):
#         """
#         Renders the field.
#         """
#         if not widget:
#             widget = self.field.widget
# 
#         # so that we can refer to the field when building the rendering context
#         widget._field = self.field
#         # Make sure that NgWidgetMixin is not already part of the widget's bases so it doesn't get added twice.
#         if not isinstance(widget, NgWidgetMixin):
#             widget.__class__ = type(widget.__class__.__name__, (NgWidgetMixin, widget.__class__), {})
#         return super(NgBoundField, self).as_widget(widget, attrs, only_initial)
# 
#     def build_widget_attrs(self, attrs, widget=None):
#         if not widget:
#             widget = self.field.widget
#         attrs = super(NgBoundField, self).build_widget_attrs(attrs, widget=widget)
#         if callable(getattr(self.field, 'update_widget_attrs', None)):
#             self.field.update_widget_attrs(self, attrs)
#         return attrs
# 
#     def label_tag(self, contents=None, attrs=None, label_suffix=None):
#         if self.field.render_label is False:
#             return ''  # label shall be rendered by the widget
#         attrs = attrs or {}
#         css_classes = getattr(self.field, 'label_css_classes', None)
#         if hasattr(css_classes, 'split'):
#             css_classes = css_classes.split()
#         css_classes = set(css_classes or [])
#         label_css_classes = getattr(self.form, 'label_css_classes', None)
#         if hasattr(label_css_classes, 'split'):
#             css_classes.update(label_css_classes.split())
#         elif isinstance(label_css_classes, (list, tuple)):
#             css_classes.update(label_css_classes)
#         elif isinstance(label_css_classes, dict):
#             for key in (self.name, '*',):
#                 extra_label_classes = label_css_classes.get(key)
#                 if hasattr(extra_label_classes, 'split'):
#                     extra_label_classes = extra_label_classes.split()
#                 extra_label_classes = set(extra_label_classes or [])
#                 css_classes.update(extra_label_classes)
#         if css_classes:
#             attrs.update({'class': ' '.join(css_classes)})
#         return super(NgBoundField, self).label_tag(contents, attrs, label_suffix='')


# Path: examples/server/tests/test_validation.py
from base64 import b64encode
from django import VERSION
from django.test import TestCase
from pyquery.pyquery import PyQuery
from server.forms.client_validation import SubscribeForm as ClientValidatedForm
from server.forms.combined_validation import SubscribeForm as CombinedValidatedForm
from djng.forms.angular_base import NgBoundField
import six

    def test_ng_length(self):
        first_name = self.dom('input[name=first_name]')
        self.assertEqual(len(first_name), 1)
        attrib = dict(first_name[0].attrib.items())
        self.assertDictContainsSubset({'ng-required': 'true'}, attrib)
        self.assertDictContainsSubset({'ng-minlength': '3'}, attrib)
        self.assertDictContainsSubset({'ng-maxlength': '20'}, attrib)
        lis = self.dom('label[for=id_first_name]').closest('th').next('td').children('ul.djng-field-errors > li')
        if VERSION[1] == 5:
            # Django < 1.6 not not know about minlength and maxlength
            self.assertEqual(len(lis), 2)
        else:
            self.assertEqual(len(lis), 4)
        attrib = dict(lis[0].attrib.items())
        self.assertDictContainsSubset({'ng-show': self.form_name + six.u('[\'first_name\'].$error.required')}, attrib)
        attrib = dict(lis[1].attrib.items())
        self.assertDictContainsSubset({'ng-show': self.form_name + six.u('[\'first_name\'].$error.minlength')}, attrib)

    def test_type(self):
        email_field = self.dom('input[name=email]')
        self.assertEqual(len(email_field), 1)
        attrib = dict(email_field[0].attrib.items())
        self.assertNotIn('required', attrib)
        self.assertDictContainsSubset({'ng-model': 'email'}, attrib)
        if VERSION[1] == 5:
            self.assertDictContainsSubset({'type': 'text'}, attrib)
        else:
            self.assertDictContainsSubset({'type': 'email'}, attrib)

    def test_regex(self):

        last_name = self.dom('input[name=last_name]')