737 and parsed. |
737 and parsed. |
738 |
738 |
739 :returns: an instance of `cubicweb.devtools.htmlparser.PageInfo` |
739 :returns: an instance of `cubicweb.devtools.htmlparser.PageInfo` |
740 encapsulation the generated HTML |
740 encapsulation the generated HTML |
741 """ |
741 """ |
742 output = None |
|
743 try: |
742 try: |
744 output = viewfunc(**kwargs) |
743 output = viewfunc(**kwargs) |
745 return self._check_html(output, view, template) |
|
746 except (SystemExit, KeyboardInterrupt): |
744 except (SystemExit, KeyboardInterrupt): |
747 raise |
745 raise |
748 except: |
746 except: |
749 # hijack exception: generative tests stop when the exception |
747 # hijack exception: generative tests stop when the exception |
750 # is not an AssertionError |
748 # is not an AssertionError |
751 klass, exc, tcbk = sys.exc_info() |
749 klass, exc, tcbk = sys.exc_info() |
752 try: |
750 try: |
753 msg = '[%s in %s] %s' % (klass, view.__regid__, exc) |
751 msg = '[%s in %s] %s' % (klass, view.__regid__, exc) |
754 except: |
752 except: |
755 msg = '[%s in %s] undisplayable exception' % (klass, view.__regid__) |
753 msg = '[%s in %s] undisplayable exception' % (klass, view.__regid__) |
756 msg = str(msg) # ensure no unicode |
|
757 if output is not None: |
|
758 position = getattr(exc, "position", (0,))[0] |
|
759 if position: |
|
760 # define filter |
|
761 output = output.splitlines() |
|
762 width = int(log(len(output), 10)) + 1 |
|
763 line_template = " %" + ("%i" % width) + "i: %s" |
|
764 # XXX no need to iterate the whole file except to get |
|
765 # the line number |
|
766 output = '\n'.join(line_template % (idx + 1, line) |
|
767 for idx, line in enumerate(output) |
|
768 if line_context_filter(idx+1, position)) |
|
769 msg += '\nfor output:\n%s' % output |
|
770 raise AssertionError, msg, tcbk |
754 raise AssertionError, msg, tcbk |
771 |
755 return self._check_html(output, view, template) |
772 |
756 |
773 @nocoverage |
757 @nocoverage |
774 def _check_html(self, output, view, template='main-template'): |
758 def _check_html(self, output, view, template='main-template'): |
775 """raises an exception if the HTML is invalid""" |
759 """raises an exception if the HTML is invalid""" |
776 output = output.strip() |
760 output = output.strip() |
790 return |
774 return |
791 validator = validatorclass() |
775 validator = validatorclass() |
792 if isinstance(validator, htmlparser.DTDValidator): |
776 if isinstance(validator, htmlparser.DTDValidator): |
793 # XXX remove <canvas> used in progress widget, unknown in html dtd |
777 # XXX remove <canvas> used in progress widget, unknown in html dtd |
794 output = re.sub('<canvas.*?></canvas>', '', output) |
778 output = re.sub('<canvas.*?></canvas>', '', output) |
795 return validator.parse_string(output.strip()) |
779 return self.assertWellFormed(validator, output.strip(), context= view.__regid__) |
|
780 |
|
781 def assertWellFormed(self, validator, content, context=None): |
|
782 try: |
|
783 return validator.parse_string(content) |
|
784 except (SystemExit, KeyboardInterrupt): |
|
785 raise |
|
786 except: |
|
787 # hijack exception: generative tests stop when the exception |
|
788 # is not an AssertionError |
|
789 klass, exc, tcbk = sys.exc_info() |
|
790 if context is None: |
|
791 msg = u'[%s]' % (klass,) |
|
792 else: |
|
793 msg = u'[%s in %s]' % (klass, context) |
|
794 msg = msg.encode(sys.getdefaultencoding(), 'replace') |
|
795 |
|
796 try: |
|
797 str_exc = str(exc) |
|
798 except: |
|
799 str_exc = 'undisplayable exception' |
|
800 msg += str_exc |
|
801 if content is not None: |
|
802 position = getattr(exc, "position", (0,))[0] |
|
803 if position: |
|
804 # define filter |
|
805 if isinstance(content, str): |
|
806 content = unicode(content, sys.getdefaultencoding(), 'replace') |
|
807 content = content.splitlines() |
|
808 width = int(log(len(content), 10)) + 1 |
|
809 line_template = " %" + ("%i" % width) + "i: %s" |
|
810 # XXX no need to iterate the whole file except to get |
|
811 # the line number |
|
812 content = u'\n'.join(line_template % (idx + 1, line) |
|
813 for idx, line in enumerate(content) |
|
814 if line_context_filter(idx+1, position)) |
|
815 msg += u'\nfor content:\n%s' % content |
|
816 raise AssertionError, msg, tcbk |
796 |
817 |
797 # deprecated ############################################################### |
818 # deprecated ############################################################### |
798 |
819 |
799 @deprecated('[3.8] use self.execute(...).get_entity(0, 0)') |
820 @deprecated('[3.8] use self.execute(...).get_entity(0, 0)') |
800 def entity(self, rql, args=None, eidkey=None, req=None): |
821 def entity(self, rql, args=None, eidkey=None, req=None): |