This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author terry.reedy
Recipients Sean.Wolfe, THRlWiTi, Todd.Rovito, gpolo, kamek, kbk, louielu, rhettinger, roger.serwy, taleinat, terry.reedy
Date 2017-06-16.00:18:07
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1497572293.35.0.714850044868.issue694339@psf.upfronthosting.co.za>
In-reply-to
Content
<<PrevWindow>> is a predefined virtual event. 
https://www.tcl.tk/man/tcl8.6/TkCmd/event.htm
I can't find <<NextWindow>> listed there. I don't remember if I actually saw it before mentioning it.  While I like mimicking smart_indent, I don't know if we can dismiss Roger Serwy's concern in msg150059.

Tk on Ubuntu may report key name ISO_Left_Tab msg150059, but it is not cross-platform.  On Win 10 with either tk 8.5.15 (2.7) or 8.6.6 (3.6):
  _tkinter.TclError: bad event type or keysym "ISO_Left_Tab"
I don't think we need to use the only sometimes valid synonym.

As Sean Wolfe reported msg212906, Shift-Tab already dedents a single line by treating it as a region.  This issue is about removing the extra behavior we don't want, and blocking Control-[ from doing simplefied non-region single line dedents.  Smart_indent does this by intercepting Tab (which I believe need not be bound to <<indent-region>>.

When there is a selection within a line, smart_indent does not call dedent_region but deletes the selection and insert \t or spaces, but in the latter case, the cursor may not be left on a multiple of indent spaces.  This does not seem very useful. It is even less so because if the selection is within a word, tab invokes autocomplete instead of smart_indent.  This needs discussion on another issue.
---

Text editing tests: how to we do them both thoroughly and efficiently (in terms of both human writing and machine execution time)?

White box approach: Set up a class test fixture that defines cls.text = <MultiCall(Text) instance>; put text in known state (content, cursor position, selection); call edit function (smart_indent, proposed smart dedent, etc); check resulting state (content, cursor, selection.  Repeat for multiple input state - output state pairs.  These tests break if the function name is changed and only test the function, which is, however, the main thing to be tested. 

Gray-box approach: Replace function calls with pseudoevents generated on the text widget.  Such tests would survive function name changes, break on pseudoevent name changes, and add a test of pseudoevent -- function binding. A black-box approach replaces pseudoevents with concrete events -- simulated key presses, mouse clicks, and menu selections.  These tests survive pseudoevent name changes and add a test of concrete -- pseudo event linkage.  They should only break if we change the user visible interface, which we seldom do. 

I think we should use all approaches in two sets of tests.  The first set would test multiple before and after states in subtests with a function call.  This would define and test the intended behavior of the function.  The second set would test one before and after state successively with a function call, pseudoevent generation, and concrete event generations, in this order.  (If the function call fails, the event tests are bound to fail.)  This would test the user interface and the links to the underlying function.

There are over 30 editing functions to test, and writing the above for all would be tedious.  After writing tests for a couple, we should write helper functions that embody the repetitive boilerplate.

An additional factor: The text edit functions, properly bound with a pseudoevent to the text instance, are not methods of the text instance (though they should be), but of the EditorWindow that also contains a Toplevel; Menu hierarchy; and a Frame that contains Scrollbars and a StatusBar, along with, finally, the MultiCall(Text) instance.  So the fixture setup must also provide provide an attribute for the method container.  Let us call it cls.widget.

In order to put EditFrames (a new subclass of Frame) on tabs, the Text methods will have to at least be transferred to the EditFrame.  It would be even better to transfer them to an IdleText subclass of MultiCall(Text) or possibly of Text.  (See Mark Roseman's suggestion of a MultiCall alternative in msg272070.)  After the setup code is changed to assign the new method container to cls.widget, the test methods should still run as they are.
History
Date User Action Args
2017-06-16 00:18:13terry.reedysetrecipients: + terry.reedy, rhettinger, kbk, kamek, taleinat, gpolo, roger.serwy, THRlWiTi, Todd.Rovito, Sean.Wolfe, louielu
2017-06-16 00:18:13terry.reedysetmessageid: <1497572293.35.0.714850044868.issue694339@psf.upfronthosting.co.za>
2017-06-16 00:18:13terry.reedylinkissue694339 messages
2017-06-16 00:18:07terry.reedycreate