source: tests/collections/string-overwrite.cfa @ ded6c2a6

ast-experimental
Last change on this file since ded6c2a6 was 0ca15b7, checked in by Michael Brooks <mlbrooks@…>, 3 years ago

String hybrid testing and fixing the overwrite cases

  • Property mode set to 100644
File size: 9.0 KB
Line 
1#include <containers/string.hfa>
2#include <string_sharectx.hfa>
3
4/*
5
6Modify a subrange of a string, while a witness is watching another subrange of the same string.
7
8Cases are the relative positions and overlaps of the modifier vs the witness.
9MS = modifier start
10ME = modifier end
11WS = witness start
12WE = witness end
13
14The test does:
15  starts with the entire string being, initially, the alphabet; prints this entire alphabet
16  sets up modifier and witness as ranges within it, and prints a visualization of those ranges
17  does the main modification
18  prints the result of the main modification, which is always an unsurprising consequence of the modifier range, but shows little about what happened to the witness, particularly if the witness is/became empty
19  modifies the witness to be "?"
20  prints the result of this second modification, which implies what the witness included after the main modification
21
22Deriving the concrete list of cases....
23
24By definition of a string, MS <= ME and WS <= WE.
25This API's convention has Start positions being inclusive and end positions being exclusive.
26
27                                v Case number in output
28With 1 equivalence class:
29MS = ME = WS = WE               1
30
31With 2 equivalence classes:
32   <    =    =
33MS   rest                       2
34WS   rest                       3
35
36   =    <    =
37MS   ME   WS   WE               4
38WS   WE   MS   ME               5
39MS   WS   ME   WE               6
40
41   =    =    <
42        rest   ME               7
43        rest   WE               8
44
45With 3 equivalence classes
46   <    <    =
47MS   ME   WS   WE               9
48     WS   ME   WE               10
49+2                              11, 12
50
51   <    =    <
52MS   WS   ME   WE               13
53          WE   ME               14
54+2                              15, 16
55
56   =    <    <
57MS   WS   WE   ME               17
58     ME   WS   WE               18
59+2                              19, 20
60
61With 4 equivalence classes
62   <    <    <
63MS   ME   WS   WE               21
64     WS   ME   WE               22
65          WE   ME               23
66+3                              24, 25, 26
67
68
69
70*/
71
72
73void showOneReplacement(string & s, int ms, int me, int ws, int we, const char* replaceWith) {
74
75    assert( ms >= 0 && ms <= me && me <= size(s) );
76    assert( ws >= 0 && ws <= we && we <= size(s) );
77
78    string mod = s(ms, me)`shareEdits;
79    string wit = s(ws, we)`shareEdits;
80
81    string modOld = mod;
82    string witOld = wit;
83
84    // s, before the mode
85    sout | s;
86
87    // visualize the pair of ranges
88    sout | nlOff;
89    for ( i; size(s) ) {
90        if( i < ms || i > me ) {
91            sout | ' ';
92        } else if ( i < me ) {
93            sout | '-';
94        } else {
95            assert ( i == me );
96            sout | '!';
97        }
98    } sout | nl;
99    for ( i; size(s) ) {
100        if( i < ws || i > we ) {
101            sout | ' ';
102        } else if ( i < we ) {
103            sout | '-';
104        } else {
105            assert ( i == we );
106            sout | '?';
107        }
108    }
109    sout | nl;
110    sout | nlOn;
111
112    mod = replaceWith;    // main replacement
113    sout | s | "( wit = " | wit | "witlen = " | size(wit) | " )";
114    wit = "?";            // witness-revelaing replacement
115    sout | s;
116}
117
118void runReplaceCases() {
119    char * alphabetTemplate = "abcdefghijklmnopqrstuvwxyz";
120    struct { int ms; int me; int ws; int we; char *replaceWith; char *label; } cases[] = {
121        { 12, 14, 10, 20, "xxxxx", "warmup" },
122        { 10, 10, 10, 10, "=====", "1"      },
123        { 10, 10, 10, 10, "=="   , ""       },
124        { 10, 10, 10, 10, "="    , ""       },
125        { 10, 10, 10, 10, ""     , ""       },
126        { 10, 12, 12, 12, "=====", "2"      },
127        { 10, 12, 12, 12, "=="   , ""       },
128        { 10, 12, 12, 12, "="    , ""       },
129        { 10, 12, 12, 12, ""     , ""       },
130        { 12, 12, 10, 12, "=====", "3"      },
131        { 12, 12, 10, 12, "=="   , ""       },
132        { 12, 12, 10, 12, "="    , ""       },
133        { 12, 12, 10, 12, ""     , ""       },
134        { 10, 10, 12, 12, "=====", "4"      },
135        { 10, 10, 12, 12, "=="   , ""       },
136        { 10, 10, 12, 12, "="    , ""       },
137        { 10, 10, 12, 12, ""     , ""       },
138        { 12, 12, 10, 10, "=====", "5"      },
139        { 12, 12, 10, 10, "=="   , ""       },
140        { 12, 12, 10, 10, "="    , ""       },
141        { 12, 12, 10, 10, ""     , ""       },
142        { 10, 12, 10, 12, "=====", "6"      },
143        { 10, 12, 10, 12, "=="   , ""       },
144        { 10, 12, 10, 12, "="    , ""       },
145        { 10, 12, 10, 12, ""     , ""       },
146        { 10, 12, 10, 10, "=====", "7"      },
147        { 10, 12, 10, 10, "=="   , ""       },
148        { 10, 12, 10, 10, "="    , ""       },
149        { 10, 12, 10, 10, ""     , ""       },
150        { 10, 10, 10, 12, "=====", "8"      },
151        { 10, 10, 10, 12, "=="   , ""       },
152        { 10, 10, 10, 12, "="    , ""       },
153        { 10, 10, 10, 12, ""     , ""       },
154        { 10, 12, 14, 14, "=====", "9"      },
155        { 10, 12, 14, 14, "=="   , ""       },
156        { 10, 12, 14, 14, "="    , ""       },
157        { 10, 12, 14, 14, ""     , ""       },
158        { 10, 14, 12, 14, "=====", "10"     },
159        { 10, 14, 12, 14, "=="   , ""       },
160        { 10, 14, 12, 14, "="    , ""       },  // FORMERLY unrunnable bug: tries to print seemingly infinite string
161        { 10, 14, 12, 14, ""     , ""       },  // ditto
162        { 14, 14, 10, 12, "=====", "11"     },
163        { 14, 14, 10, 12, "=="   , ""       },
164        { 14, 14, 10, 12, "="    , ""       },
165        { 14, 14, 10, 12, ""     , ""       },
166        { 12, 14, 10, 14, "=====", "12"     }, // correctness observation:  watching klmn while mn |-> xxx gives klxxx because the mn is inside what I'm watching
167        { 12, 14, 10, 14, "=="   , ""       },
168        { 12, 14, 10, 14, "="    , ""       },
169        { 12, 14, 10, 14, ""     , ""       },
170        { 10, 12, 12, 14, "=====", "13"     },
171        { 10, 12, 12, 14, "=="   , ""       },
172        { 10, 12, 12, 14, "="    , ""       },
173        { 10, 12, 12, 14, ""     , ""       },
174        { 10, 14, 12, 12, "=====", "14"     },
175        { 10, 14, 12, 12, "=="   , ""       },
176        { 10, 14, 12, 12, "="    , ""       },
177        { 10, 14, 12, 12, ""     , ""       },
178        { 12, 14, 10, 12, "=====", "15"     },
179        { 12, 14, 10, 12, "=="   , ""       },
180        { 12, 14, 10, 12, "="    , ""       },
181        { 12, 14, 10, 12, ""     , ""       },
182        { 12, 12, 10, 14, "=====", "16"     },
183        { 12, 12, 10, 14, "=="   , ""       },
184        { 12, 12, 10, 14, "="    , ""       },
185        { 12, 12, 10, 14, ""     , ""       },
186        { 10, 14, 10, 12, "=====", "17"     },
187        { 10, 14, 10, 12, "=="   , ""       },
188        { 10, 14, 10, 12, "="    , ""       },
189        { 10, 14, 10, 12, ""     , ""       },
190        { 10, 10, 12, 14, "=====", "18"     },
191        { 10, 10, 12, 14, "=="   , ""       },
192        { 10, 10, 12, 14, "="    , ""       },
193        { 10, 10, 12, 14, ""     , ""       },
194        { 10, 12, 10, 14, "=====", "19"     },
195        { 10, 12, 10, 14, "=="   , ""       },
196        { 10, 12, 10, 14, "="    , ""       },
197        { 10, 12, 10, 14, ""     , ""       },
198        { 12, 14, 10, 10, "=====", "20"     },
199        { 12, 14, 10, 10, "=="   , ""       },
200        { 12, 14, 10, 10, "="    , ""       },
201        { 12, 14, 10, 10, ""     , ""       },
202        { 10, 12, 14, 16, "=====", "21"     },
203        { 10, 12, 14, 16, "=="   , ""       },
204        { 10, 12, 14, 16, "="    , ""       },
205        { 10, 12, 14, 16, ""     , ""       },
206        { 10, 14, 12, 16, "=====", "22"     },
207        { 10, 14, 12, 16, "=="   , ""       },
208        { 10, 14, 12, 16, "="    , ""       },
209        { 10, 14, 12, 16, ""     , ""       },
210        { 10, 16, 12, 14, "=====", "23"     },
211        { 10, 16, 12, 14, "=="   , ""       },
212        { 10, 16, 12, 14, "="    , ""       },
213        { 10, 16, 12, 14, ""     , ""       },
214        { 14, 16, 10, 12, "=====", "24"     },
215        { 14, 16, 10, 12, "=="   , ""       },
216        { 14, 16, 10, 12, "="    , ""       },
217        { 14, 16, 10, 12, ""     , ""       },
218        { 12, 16, 10, 14, "=====", "25"     },
219        { 12, 16, 10, 14, "=="   , ""       },
220        { 12, 16, 10, 14, "="    , ""       },
221        { 12, 16, 10, 14, ""     , ""       },
222        { 12, 14, 10, 16, "=====", "26"     },
223        { 12, 14, 10, 16, "=="   , ""       },
224        { 12, 14, 10, 16, "="    , ""       },
225        { 12, 14, 10, 16, ""     , ""       },
226    };
227    for ( i; sizeof(cases)/sizeof(cases[0]) ) {
228        sout | "------------------------------------------------------------------------" | cases[i].label;
229        string replaceIn = alphabetTemplate;
230        showOneReplacement( replaceIn, cases[i].ms, cases[i].me, cases[i].ws, cases[i].we, cases[i].replaceWith );
231    }
232}
233
234
235int main() {
236
237    #ifdef STRING_SHARING_OFF
238    string_sharectx c = { NO_SHARING };
239    #endif
240
241
242    //          0         1         2
243    //          01234567890123456789012345
244    string s = "abcdefghijklmnopqrstuvwxyz";
245
246    s(5,10) = "qqqqq";  // start=5, end=10, len=5
247
248    sout | s;
249
250
251    s(5,5) = "-----";  // start=5, end=5, len=0
252
253    sout | s;
254
255    runReplaceCases();
256}
Note: See TracBrowser for help on using the repository browser.