/src/Editing/Tests.hs
Haskell | 464 lines | 409 code | 23 blank | 32 comment | 26 complexity | 3e418083181f2f751a6c7f5277af3a7b MD5 | raw file
1{-# LANGUAGE UnicodeSyntax #-} 2 3module Main (main) where 4 5import qualified Editing.EditsPreparation 6import qualified Editing.Parse 7import qualified Editing.Execute 8import qualified Editing.Diff 9import qualified Cxx.Show 10import qualified Cxx.Parse 11 12import Parsers (eof, parseOrFailE) 13import Util (test_cmp, (<<), (.)) 14import Request (EditableRequest(..), EditableRequestKind(..)) 15 16import Prelude hiding ((.)) 17import Data.SetOps 18 19basic_tests :: IO () 20basic_tests = do 21 f "" "make foo bar bas" "Unexpected end of command. Expected \"::\" or template-arguments." 22 f "" "make " "Unexpected end of command. Expected \"declaration\", \"body\", production-name, \"all\", \"any\", \"every\", \"each\", ordinal, or declarator-id." 23 f "" "make i pointer to" "Unexpected end of command. Expected type description." 24 s "mutable int i;" "make i const" "const mutable int i;" 25 s "int i;" "make i a const double" "double const i;" 26 s "int const i;" "make i a double" "double const i;" 27 s "void g(int); void f() { bind(&g)(3, 2); }" "make g a function taking two integers" "void g(int, int); void f() { bind(&g)(3, 2); }" 28 -- "bind(&g)(3, 2);" is determined not to be declaration because it would be a reference initialized with two arguments. 29 s "int i;" "make i a *&" "int *& i;" 30 s "int * p = f();" "make p auto" "auto p = f();" 31 s "inline void f();" "make f noninline" "void f();" 32 s "int (* const i)(double);" "make i nonconst" "int (* i)(double);" 33 s "int i;" "make i a pointer&" "int *& i;" 34 f "int i;" "make j const" "Could not find free declaration of j." 35 s "void f() { int i; i; i = 0; }" "make i a pointer" "void f() { int * i; i; i = 0; }" 36 s "struct X { static void f(); }" "append semicolon and make f pure" "struct X { virtual void f()= 0 ; };" 37 s "struct X { virtual void f() = 0; };" "make f static" "struct X { static void f() ; };" 38 s "struct X { void f(); };" "make f virtual pure const inline explicit" "struct X { virtual inline explicit void f()const = 0 ; };" 39 s "struct X { ~X(); };" "make ~ X virtual" "struct X { virtual ~X(); };" 40 s "struct X { virtual inline explicit void f()const = 0 ; };" "make f impure nonvirtual nonexplicit noninline" "struct X { void f()const ; };" 41 s "struct X { X(int i); };" "make i a reference to const and make constructor explicit" "struct X { explicit X(const int & i); };" 42 s "int *p;" "make p a const*volatile" "const int *volatile p;" 43 s "void N::f() {}" "make N::f inline" "inline void N::f() {}" 44 s "struct X { void operator++(); };" "make operator++ a const function returning an X&" "struct X { X & operator++()const ; };" 45 s "int x /*haha*/ ; // ok dan /* mja */" "make x const" "const int x /*haha*/ ; // ok dan /* mja */" 46 s "T const ( &f() )[3] { T x = {v}; }" "make f inline" "inline T const ( &f() )[3] { T x = {v}; }" 47 s "int *i; int * & j;" "make i a pointer to a pointer" "int ** i; int * & j;" 48 s "struct Factorial { static int v = N; };" "make v const" "struct Factorial { const static int v = N; };" 49 s "{ struct S {}; int (S:: * p) = 0; int (S:: * & r) = p; }" "make p and r const" "{ struct S {}; int (S:: * const p) = 0; int (S:: * const & r) = p; }" 50 s "int i;" "make i an array" "int i[];" 51 s "void f() { try { int long i; } catch(int long j) {} }" "make i and j long long" "void f() { try { long long int i; } catch(long long int j) {} }" 52 s "void f() { try { long long i; } catch(long long j) {} }" "make i and j long" "void f() { try { long i; } catch(long j) {} }" 53 s "int i;" "make i a const array" "const int i[];" 54 s "int i;" "make i a const array of pointers" "int *const i[];" 55 s "int i[];" "make i const" "const int i[];" 56 s "struct X { ~X(); }" "append ; and make destructor virtual and show" "struct X { virtual ~X(); };" 57 s "{ try{}catch(const int i){} }" "make i volatile" "{ try{}catch(volatile const int i){} }" 58 s "void f(int i, double d){}" "make i and d long" "void f(long int i, long double d){}" 59 s "void f(int i, int j, int k);" "make second parameter-declaration const and erase third parameter-declaration" "void f(int i, const int j);" 60 s "void f(float, int, char, double);" "make second and third parameter-declaration const" "void f(float, const int, const char, double);" 61 s "{ if(int i = 3) ; }" "make i const" "{ if(const int i = 3) ; }" 62 s "int i;" "make i an array of const" "const int i[];" 63 s "int i;" "make i a static const function" "static int i()const ;" 64 s "int i;" "make i a pointer to a function" "int (* i)();" 65 s "int i;" "make i a pointer to a function taking two doubles" "int (* i)(double, double);" 66 s "int i;" "make i a function returning a const" "const int i();" 67 s "int i;" "make i a function returning a const pointer and taking a bool" "int *const i(bool);" 68 s "{ cout << 3, 3.2, 3ul, 3e+2, 0x3, 03, .3, 3., .3e1, 3.E0; int i; }" "make i const" "{ cout << 3, 3.2, 3ul, 3e+2, 0x3, 03, .3, 3., .3e1, 3.E0; const int i; }" 69 s "void f(int i) { try {} catch(int j) {} }" "make f and i and j const" "void f(const int i) const { try {} catch(const int j) {} }" 70 f "void f(int i) { try {} catch(int j) {} }" "make j mutable" "Invalid decl-specifier for type-specifier-seq: mutable" 71 s "struct X { void f(int p); };" "make f static inline and make p a reference to long" "struct X { static inline void f(long int & p); };" 72 s "struct X { operator ()(); };" "make operator() const" "struct X { operator ()()const ; };" -- Spaces don't matter when matching declarator-ids. 73 s "<< 3, i; int i = 2;" "make i const" "<< 3, i; const int i = 2;" 74 putStrLn "All make tests passed." 75 76 t "erase all 2 and insert x before second 3 and prepend y" $ Right "y1 3 x3 4 5" 77 t "erase everything before last 2 and replace everything after 4 with x" $ Right "2 3 4x" 78 t "insert x after all 2 and append y" $ Right "1 2x 3 2x 3 4 5y" 79 t "erase first 2 and replace second 2 with x and omit last " $ Right "1 3 x 3 45" 80 t "erase first and last 2 and all 3 and 4 and everything before first 2 and everything after 4" $ Right " " 81 t "erase third last space and kill everything after second last " $ Right "1 2 3 23 " 82 t "insert x after 1 2 and before all 3 and erase 5 and prepend y" $ Right "y1 2x x3 2 x3 4 " 83 t "erase everything before 4 and everything after 5" $ Right "4 5" 84 t "insert x before 3 4 and 5" $ Right "1 2 3 2 x3 4 x5" 85 t "insert x after 1 and all 3 and before 5 and erase 4" $ Right "1x 2 3x 2 3x x5" 86 t "erase second space before 4" $ Right "1 2 3 23 4 5" 87 t "erase first 2 3 and 3 2 and 4 5 and last " $ Right "1 3 " 88 t "move 1 till second 3 to before 5" $ Right "3 4 1 2 3 2 5" 89 t "move 1 till after second 3 to before 5" $ Right " 4 1 2 3 2 35" 90 t "swap last 2 3 and last space before 4" $ Right "1 2 3 2 34 5" 91 t "swap last 2 3 with last space before 4" $ Right "1 2 3 2 34 5" 92 t "swap 1 and first 3 and second 3 and 5" $ Right "3 2 1 2 5 4 3" 93 t "replace 2 after second space with x" $ Right "1 2 3 x 3 4 5" 94 t "move everything till 4 to end and erase 4 " $ Right "51 2 3 2 3 " 95 t "erase everything" $ Right "" 96 t "insert x after second space before 4" $ Right "1 2 3 2 x3 4 5" 97 t "add < and > around second 3" $ Right "1 2 3 2 <3> 4 5" 98 t "add braces around everything" $ Right "{1 2 3 2 3 4 5}" 99 t "move everything after second 3 to begin" $ Right " 4 51 2 3 2 3" 100 t "move second 3 to end and 5 to begin" $ Right "51 2 3 2 4 3" 101 t "erase first space until second space before 4" $ Right "1 3 4 5" 102 t "erase spaces" $ return "1232345" 103 t "erase second last space before 4" $ Right "1 2 3 23 4 5" 104 t "erase after second 2" $ Right "1 2 3 2" 105 t "erase after second 2 until before 5" $ Right "1 2 3 25" 106 t "erase 1 and erase 1" $ Right " 2 3 2 3 4 5" 107 t "erase before second last space" $ Right " 4 5" 108 t "move 4 5 to before 1 and erase everything after second 2" $ Right "4 51 2 3 2" 109 t "erase everything between last and first 2" $ Right "1 22 3 4 5" 110 t "erase everything between second 2 and begin" $ Right "2 3 4 5" 111 t "erase all space between second 2 and 4" $ Right "1 2 3 234 5" 112 t "erase from first 3 until after everything" $ Right "1 2 " 113 t "erase 2 after and before first 3" $ return "1 3 3 4 5" 114 t "add + before and after 4" $ return "1 2 3 2 3 +4+ 5" 115 t "move before second 3 until 4 to begin" $ Right "3 1 2 3 2 4 5" 116 t "erase everything between begin and end" $ Right "" 117 t "move everything between first 3 and 4 to begin" $ Right " 2 3 1 2 34 5" 118 t "erase before second 3 until 4" $ Right "1 2 3 2 4 5" 119 t "insert x before second 3 and at end" $ Right "1 2 3 2 x3 4 5x" 120 t "erase until after second 3" $ Right " 4 5" 121 t "erase from before second 3" $ Right "1 2 3 2 " 122 t "replace all but first and second last space with x" $ Right "1 2x3x2x3 4x5" 123 t "change all but first and second last space to x" $ Right "1 2x3x2x3 4x5" 124 t "erase between second and fourth space and 1" $ Right " 2 3 4 5" 125 t "erase between the first and third space and prepend x" $ Right "x1 2 3 4 5" 126 t "add parentheses around every space between first 2 and 4 and around 5 and erase second last 3" $ Right "1 2( )( )2( )3( )4 (5)" 127 t "move from first 3 until 4 to begin" $ Right "3 2 3 41 2 5" 128 t "erase everything from before everything until the second 3" $ Right "3 4 5" 129 t "add parentheses around first 2 and 5" $ Right "1 (2) 3 2 3 4 (5)" 130 t "erase everything between first space and last space" $ Right "1 5" 131 t "erase all 3 and all 2 between begin and end" $ Right "1 4 5" 132 t "erase everything between second and first 2 " $ Right "1 2 2 3 4 5" 133 t "erase from second 2 till last space" $ Right "1 2 3 5" 134 t "erase from second 2 until after 3 and add x before 4" $ Right "1 2 3 x4 5" 135 -- t "erase everything between 1 and the second 2 and everything between 4 and 5" $ Right "12 3 45" 136 t "erase from before 4 until end" $ Right "1 2 3 2 3 " 137 t "use 5x and y4" $ Right "1 2 3 2 3 y4 5x" 138 t "erase everything from after 1 until second last space" $ Right "1 4 5" 139 t "add parentheses around everything between 1 and second space before 4" $ Right "1( 2 3 2) 3 4 5" 140 t "add + and - around all 3 and second 2 and prepend x" $ Right "x1 2 +3- +2- +3- 4 5" 141 t "move 4 till end to front" $ Right "4 51 2 3 2 3 " 142 t "erase all space after first 2" $ Right "1 232345" 143 t "add x before first 3 after second 2" $ Right "1 2 3 2 x3 4 5" 144 t "add x before second space after second 3" $ Right "1 2 3 2 3 4x 5" 145 t "add x after all space before first 3" $ Right "1 x2 x3 2 3 4 5" 146 t "erase all space before last 3" $ Right "12323 4 5" 147 t "erase second 2 till end" $ Right "1 2 3 " 148 t "append x before 5 and prepend y before all 2 between first 3 and 5" $ Right "1 2 3 y2 3 4 x5" 149 t "move everything after second 3 to begin" $ Right " 4 51 2 3 2 3" 150 t "replace first 2 with x and replace all 2 with x" $ Right "1 x 3 x 3 4 5" 151 t "erase everything until 4 and 5" $ Right "4 " 152 t "erase 3 2 till 5" $ Right "1 2 5" 153 t "move second 2 to back and prepend x" $ Right "x1 2 3 3 4 52" 154 t "cut everything before first 2 and first and second 3 and everything after 4 and prepend x" $ Right "x2 2 4" 155 t "replace all 2 with 3 and erase all 3 and add x after second 2" $ Right "1 3 3x 4 5" 156 t "insert spacer before 4 and insert a semicolon after 1 and erase last space" $ Right "1; 2 3 2 3 spacer45" 157 t "erase first and second last " $ Right "12 3 2 34 5" 158 t "replace 1 with x and all 2 with y and erase second 3" $ Right "x y 3 y 4 5" 159 t "move everything after last 3 to front and erase 5" $ Right " 4 1 2 3 2 3" 160 t "erase spaces around first 2" $ Right "123 2 3 4 5" 161 t "erase spaces around 3 after second 2" $ Right "1 2 3 234 5" 162 t "erase 1 and 2 around first space" $ Right " 3 2 3 4 5" 163 t "erase all but first two spaces" $ Right "1 2 32345" 164 t "add x after 4 and add y after 4" $ Right "1 2 3 2 3 4yx 5" 165 t "erase 4 and add y before 4 and add x after 4" $ Right "1 2 3 2 3 yx 5" 166 t "move 4 to end and insert x before 5" $ Right "1 2 3 2 3 x54" 167 t "erase 4 and move 5 to begin" $ Right "51 2 3 2 3 " 168 t "move 3 2 3 to front and insert x before second 2" $ Right "3 x2 31 2 4 5" 169 t "append float x; int y;" $ Right "1 2 3 2 3 4 5float x; int y;" 170 t "erase 5 and move everything after last 3 to front" $ Right " 4 1 2 3 2 3" 171 t "move everything before 4 to end and move first 3 to front" $ Right "34 51 2 2 3 " 172 t "move 3 4 5 to before 4" $ Left "Move destination lies in source range." 173 t "move 1 and 4 to after first 3" $ Right " 2 314 2 3 5" 174 -- Order-sensitive edits: 175 t "add parentheses around everything and append x" $ Right "(1 2 3 2 3 4 5)x" 176 t "add parentheses around all 3 and all 2 and erase 4" $ Right "1 (2) (3) (2) (3) 5" 177 t "append x and add parentheses around everything" $ Right "(1 2 3 2 3 4 5x)" 178 t "append x after everything before 4 and add y before 4" $ Right "1 2 3 2 3 xy4 5" 179 t "insert y before 4 and insert z after second 3 " $ Right "1 2 3 2 3 zy4 5" 180 t "prepend x and move 5 to begin and insert y before 1 and insert z before everything" $ Right "z5xy1 2 3 2 3 4 " 181 t "add parentheses around everything and prepend x" $ Right "x(1 2 3 2 3 4 5)" 182 t "prepend x and add parentheses around everything" $ Right "(x1 2 3 2 3 4 5)" 183 t "prepend x before everything after 4 and add y after 4" $ Right "1 2 3 2 3 4yx 5" 184 t "add y after 4 and prepend x before everything after 4" $ Right "1 2 3 2 3 4xy 5" 185 -- Semantic edits: 186 ct "a x;" "add b after first identifier" $ Right "ab x;" 187 ct "struct X { operator bool() { return true; } };" "move declaration of operator bool to end" $ Right "struct X { };operator bool() { return true; } " 188 ct "namespace N { void f(); } class C { void g() {} };" "swap body of N and body of C" $ Right "namespace N { void g() {} } class C { void f(); };" 189 ct "void f() { int i; } void g() { int j; } void h() {}" "prepend BARK; in f and append BARK; in g and in h" $ Right "void f() { BARK;int i; } void g() { int j; BARK;} void h() {BARK;}" 190 ct "class C { int f() {} };" "add int x; in C and add return x; in f" $ Right "class C { int f() {return x;} int x;};" 191 ct "void f() { cout << 3; g(); }" "erase everything from after 3; until after body of f" $ Right "void f() { cout << 3;}" 192 ct "int main() { cout << 3; }" "move << 3 to front and erase declaration of main" $ Right "<< 3" 193 ct "{ cout << x; } enum E { x };" "add `cout, y;` in main and add ,y in E" $ Right "{ cout << x; cout, y;} enum E { x ,y};" 194 ct "namespace N { void f(); void g(); void f(); } void h();" "add int x; after declaration of g in N" $ Right "namespace N { void f(); void g();int x; void f(); } void h();" 195 ct "struct X { void f(); }; struct Y { void f(); };" "erase declaration of f in Y" $ Right "struct X { void f(); }; struct Y { };" 196 ct "namespace N { void f(); void g(); void f(); } void h();" "move declaration of h to after declaration of g in N" $ Right "namespace N { void f(); void g(); void h();void f(); } " 197 ct "void f() {} void g() {} namespace N { void f() {} } void f(int) {}" "add int x; in f in N and in g and append y" $ Right "void f() {} void g() {int x;} namespace N { void f() {int x;} } void f(int) {}y" 198 ct "void f() { int x; } void g() { int x; } void h() { int x; }" "erase declaration of x in f and h" $ Right "void f() { } void g() { int x; } void h() { }" 199 ct "namespace N { int x; } int x; void f() { int x; }" "use int y; in N and f" $ Right "namespace N { int y; } int x; void f() { int y; }" 200 ct "void f() {} void f(int) {} void f(double) {} void f(char) {}" "add int x; in first f and in third and fourth body of f" $ Right "void f() {int x;} void f(int) {} void f(double) {int x;} void f(char) {int x;}" 201 ct "namespace A { int x; namespace B { int x; namespace C { int x; namespace D { int x; } } } }" "erase declaration of x in D in C in B in A" $ Right "namespace A { int x; namespace B { int x; namespace C { int x; namespace D { } } } }" 202 ct "struct X { X(int); };" "erase second declaration of X" $ Right "struct X { };" 203 ct "template <typename> void f(); void f(int);" "erase second declaration of f" $ Right "template <typename> void f(); " 204 ct "struct X { template <typename U> X(U); };" "erase second declaration of X" $ Right "struct X { };" 205 ct "struct X { int x; X(); void f(); ~X(); struct Y {}; operator int(); X(int); };" "erase constructors and replace destructor with int y;" $ Right "struct X { int x; void f(); int y; struct Y {}; operator int(); };" 206 ct "template <typename T> struct X { template <typename U> inline X(T, U); ~X(); }; template <typename T> template <typename U> X<T>::X(T, U) {} template<typename T> X<T>::~X() {}" "erase second constructor and second destructor" $ Right "template <typename T> struct X { template <typename U> inline X(T, U); ~X(); }; " 207 ct "void f(int i);" "erase declaration of i" $ Right "void f();" 208 ct "struct X { int i; };" "erase declaration of i" $ Right "struct X { };" 209 ct "{ 3; 4; 5; }" "swap first and last statement" $ Right "{ 5; 4; 3; }" 210 ct "{ 3; 4; 5; }" "swap statements around 4;" $ Right "{ 5; 4; 3; }" 211 ct "{ 3; 4; 5; 6; }" "swap statements before 5 with last statement" $ Right "{ 6; 5; 3; 4; }" 212 ct "void f(int,double,char);" "swap first two parameter-declarations" $ return "void f(double,int,char);" 213--todo: ct "{ if(b) 3; 4; 5; }" "add curlies around first two statements after if" $ Right "{ if(b) {3; 4;} 5; }" 214--todo: ct "{ 3; 4; 5; }" "add curlies around first and second statement" $ Right "{ {3; 4;} 5; }" 215 ct "{ 3; 4; 5; }" "add curlies around first statement and around second statement" $ Right "{ {3;} {4;} 5; }" 216 ct "<< max(3, 2, 1)" "add curlies around code between parens" $ return "<< max({3, 2, 1})" 217 ct "{ 1;2;3;4;5; }" "swap first two statements with last two statements" $ Right "{ 4;5; 3;1;2;}" 218 ct "{ 1;2;3; }" "swap first two statements" $ Right "{ 2;1;3; }" 219 --ct "void f() { 1; } void g() { 1; 2; 3; 4; }" "replace first two and last statement in g with 0;" $ Right "void f() { 1; } void g() { 0;3; 0;}" 220 ct "void f() { int x = 3; cout << x; } int i;" "replace everything after first statement in f with BARK;" $ Right "void f() { int x = 3; BARK;} int i;" 221 ct "template <typename T, int i> struct S;" "erase second template-parameter" $ return "template <typename T> struct S;" 222 ct "void g(string s); void f(int i, double d, char c, float, bool b);" "erase first and last two parameter-declarations in declaration of f and replace third parameter-declaration in declaration of f with wchar_t c" $ return "void g(string s); void f(double d, wchar_t c);" 223 ct "int f();" "replace type-specifier with void" $ Right "void f();" 224 ct "void g() { 0; struct X { void f() { 1;2;3;4; } }; 1; }" "erase statements around 2 in f" $ Right "void g() { 0; struct X { void f() { 2;} }; 1; }" 225 ct "int a;in@@@t x;int y;int z;" "erase @@@ and erase int a; and erase second declaration" $ Right "int y;int z;" 226 ct "@ int x;" "erase @ and replace declaration of x by bla" $ return " bla" 227 ct "@@@@@ void f(){} int x;" "erase @@@@@ and erase first x after function-definition" $ Right " void f(){} int ;" 228 ct "@@@@int x; int y; int z;" "erase @@@@ and erase from start until second declaration" $ Right "int z;" 229 ct "@@@@int x; int y; int z;" "erase @@@@ and erase from second declaration until last space" $ Right "int x; z;" 230 ct "class X extends Y { int i:2; };" "replace extends with : and replace literal after : with 3" $ Right "class X : Y { int i:3; };" 231 ct "T f() { 0;x; } U y;" "erase everything after 0 in f" $ Right "T f() { 0} U y;" 232 ct "T f() { 0;x; } U y;" "erase everything before x in f" $ Right "T f() { x; } U y;" 233 ct "T f() { 0;1;2;3;4; } U y;" "erase everything between second and fourth statement in f" $ Right "T f() { 0;1;3;4; } U y;" 234 ct "; void g() {} void f() { {1;} }" "erase first semicolon and erase curlies around 1;" $ return " void g() {} void f() { 1; }" 235 -- Edit errors: 236 ct "struct X { void f() { cout << 3; int x; cout << 3; } };" "erase second 3 after declaration of x in f in X" $ Left "String `3` does not occur twice after free declaration of x in f in X." 237 t "erase second 4 after 1" $ Left "String `4` does not occur twice after 1." 238 t "move second 2 to x" $ Left "Unexpected `x` after `second 2 to `. Expected \"beginning\", \"begin\", \"front\", \"start\", \"end\", \"back\", \"before\", or \"after\"." 239 t "replace alligators with chickens" $ Left "String `alligators` does not occur." 240 t "use banana" $ Left "No non-exact match for banana." 241 t "use 5426" $ Left "No non-exact match for 5426." 242 t "erase 2" $ Left "String `2` occurs multiple times." 243 t "replace 1 and erase with 4" $ Left "String `erase` does not occur." 244 t "replace tenth last 2 by x" $ Left "String `2` does not occur 10 times." 245 t "erase second 9" $ Left "String `9` does not occur." 246 t "replace all 2 with 3 and replace second 2 with x" $ Left "Overlapping edits: replace 2 with 3 and replace 2 with x." 247 t "erase everything before first 3 and replace first 2 with x" $ Left "Overlapping edits: erase `1 2 ` and replace 2 with x." 248 t "erase 5 between 1 and 4" $ Left "String `5` does not occur between 1 and 4." 249 t "prepend x and replace 4 with a and replace 4 with b" $ Left "Overlapping edits: replace 4 with a and replace 4 with b." 250 -- Syntax errors: 251 t "isnert 3 before 4" $ Left "Unexpected `isnert` at start. Expected edit command." 252 t "insert " $ Left "Unexpected end of command. Expected option, wrapping description, or verbatim string." 253 t "insert kung fu" $ Left "Unexpected end of command. Expected \" and\", \" in\", \" at\", \" around\", \" before\", or \" after\"." 254 t "move " $ Left "Unexpected end of command. Expected \"till\", \"until\", \"from\", \"everything\", \"code\", \"before\", \"between\", \"after\", \"declaration\", \"body\", production-name, verbatim string, \"all\", \"any\", \"every\", \"each\", or ordinal." 255 t "move x " $ Left "Unexpected end of command. Expected \" till\", \" until\", \" around\", \" before\", \" after\", \" between\", \" in\", \" and\", or \" to\"." 256 t "move x to "$ Left "Unexpected end of command. Expected \"beginning\", \"begin\", \"front\", \"start\", \"end\", \"back\", \"before\", or \"after\"." 257 t "erase all 2 and " $ Left "Unexpected end of command. Expected verbatim string, \"till\", \"until\", \"from\", \"everything\", \"code\", \"before\", \"between\", \"after\", \"declaration\", \"body\", production-name, \"all\", \"any\", \"every\", \"each\", ordinal, wrapping description, option, or edit command." 258 putStrLn "All basics tests passed." 259 260 where 261 ct :: String → String → Either String String → IO () 262 ct x c o = test_cmp c o $ case parseOrFailE (Editing.Parse.commandsP << eof) c "command" of 263 Left e → Left e 264 Right (cmds, _) → editable_body . Editing.Execute.execute Nothing cmds (EditableRequest (Evaluate (∅)) x) 265 266 s, f :: String → String → String → IO () 267 s code cmdstring expectation = ct code cmdstring (Right expectation) -- test for success 268 f code cmdstring expectation = ct code cmdstring (Left expectation) -- test for failure 269 270 t = ct "1 2 3 2 3 4 5" 271 272diff_tests :: IO () 273diff_tests = do 274 275 dt' "foo; bar; monkey; chicken; bas;" "bar; monkey; chicken;" "Erased `foo;` and `bas;`." "Prepended `foo;` and appended `bas;`." 276 277 dt' "{ fstream f(\"t.cpp\"); string s(istreambuf_iterator<char>(f), istreambuf_iterator<char>()); }" 278 "{ fstream f(\"t.cpp\"); string s((istreambuf_iterator<char>(f)), istreambuf_iterator<char>()); }" 279 "Inserted ( before `istreambuf_iterator<char>`, and inserted ) after `istreambuf_iterator<char>(f)`." 280 "Erased ( before `istreambuf_iterator<char>` and ) after `istreambuf_iterator<char>(f)`." 281 -- Todo: One day, the former should say "wrapped ...". 282 283 dt' "int f(int & i) { i = 4; return i;} int g(int && i){return f(i);} int main() { cout << g(2); }" 284 "int & f(int & i) { i = 4; return i;} int & g(int && i){return f(i);} int & g(int & i){return f(i);} int main() { cout << g(2); }" 285 "Replaced `int f` with `int & f`, replaced `int g` with `int & g`, and inserted `int & g(int & i){return f(i);}` before `int main`." 286 "Replaced `int & f` with `int f`, replaced `int & g` with `int g`, and erased `int & g(int & i){return f(i);}`." 287 288 dt' "{string foo = \"kangaroo\"; auto m = foo.find_first_of('m'); cout << *m;}" 289 "{string foo = \"kangaroo\"; size_t m = foo.find_first_of('m'); cout << foo[m];}" 290 "Replaced `auto m` with `size_t m`, and replaced `<< *m` with `<< foo[m]`." 291 "Replaced `size_t m` with `auto m`, and replaced `<< foo[m]` with `<< *m`." 292 -- Todo: Group. 293 294 dt "{int i=0,t=time(0);for(;i<5000000;i++)asm(\".org 0xffff\");cout << time(0)-t; }" 295 "{int i=0,t=time(0);for(;i<5000;i++)int tmp=1*88+71/4000^66;cout << time(8)-t; }" 296 "Replaced i<5000000 with i<5000, replaced `asm(\".org 0xffff\")` with `int tmp=1*88+71/4000^66`, and replaced 0 with 8." 297 298 dt' "struct curr_func { string name; cf(string n):name(n){} }; \\ #define DEFUN(name) name try { throw curr_func(#name); } catch(curr_func& cfun) \\ DEFUN(void haha(int a)) { cout << cfun.name; } int main() { cout << haha; }" 299 "struct curr_func { string name; curr_func(string n):name(n){} }; \\ #define DEFUN(name) name try { throw curr_func(#name); } catch(curr_func& cfun) \\ DEFUN(void haha(int a)) { cout << cfun.name << \": \" << a; } int main() { haha(42); }" 300 "Replaced cf with curr_func, inserted `<< \": \" << a` after `<< cfun.name`, and replaced `cout << haha` with haha(42)." 301 "Replaced curr_func with cf, erased `<< \": \" << a`, and replaced haha(42) with `cout << haha`." 302 303 dt "{float i=0,t=time(0);for(;i<5000000;i++) { if(x == 3) f(reinterpret_cast<long>(x)); } }" 304 "{int i=0,t=time(null);for(;i<5000000;++i) { if(x != 3) f(static_cast<long>(x)); } }" 305 "Replaced `float i` with `int i`, replaced 0 with null, replaced i++ with ++i, replaced `x == 3` with `x != 3`, and replaced `reinterpret_cast<long>` with `static_cast<long>`." 306{- 307 dt' "struct a { int b; a():b([]{ return 1 + 2 + 3; }){}}a_; int main() { cout << a_.b }" 308 "struct a { int b; a({}):b([]{ return 1 + 2 + 3; }()){}}a_; int main() { cout << a_.b; }" 309 "Replaced \"a():b([]{\" with \"a({}):b([]{\", replaced \")\" after \"return 1 + 2 + 3; }\" with \"())\", and inserted \";\" after \"cout << a_.b\"." 310 "Replaced \"a({}):b([]{\" with \"a():b([]{\", replaced \"}()){}}a_\" with \"}){}}a_\", and erased \";\" after \"cout << a_.b\"." 311-} 312 dt "struct curr_func { string name; cf(string n):name(n){} }; \\ #define DEFUN(name) name try { throw curr_func(#name); } catch(curr_func& cfun) \\ DEFUN(void haha(int a)) { cout << cfun.name; } int main() { cout << haha; }" 313 "struct { string name; cf(string n){} }; \\ #define DEFUN(name) name try { } catch(curr_func& cfun) \\ DEFUN(void haha(int a) { cout << \"tortoise\"; } ) { cout << ETYPE(cfun.name); } int main() { do_something(complicated); cout << haha; }" 314 "Replaced `struct curr_func` with struct, erased :name(n) and `throw curr_func(#name);`, inserted `{ cout << \"tortoise\"; }` before `) { cout`, replaced `<< cfun.name` with `<< ETYPE(cfun.name)`, and inserted `do_something(complicated);` before `cout << haha`." 315{- 316 dt "{ char str[] = \"giraffe\"; char * pch; pch=(char*) memchr(str, 'y', (int)strlen(str)); if (pch!=NULL) { printf(\"'y' was found at position #%d\", pch-str+1); } }" 317 "{ char * str = \"giraffe\"; char * pch; pch=(char*) memchr(str, 'v', (size_t)strlen(str)); if (pch!=NULL) { printf(\"'v' was found at position #%d\", pch-str-1); memset(str, '*', 6); puts(str); printf(\"%s\", str); } }" 318 "Replaced `char str[]` with `char * str`, replaced 'y' with 'v', replaced int with size_t, replaced `\"'y' was` with `\"'v' was`, and replaced pch-str+1 with `pch-str-1); memset(str, '*', 6); puts(str); printf(\"%s\", str`." 319-} 320 dt "geordi: { char y(34); stringstream i(\"geordi: { char y(34); stringstream i(!); string t; getline(i, t, '!'); cout << t << y << i.str() << y << i.rdbuf(); }\"); string t; getline(i, t, '!'); cout<< t << y << i.str() << y << i.rdbuf(); }" 321 "geordi: { stringstream i(\"geordi: { stringstream i(!); string t; getline(i, t, '!'); cout << t << i.str() << i.rdbuf(); }\"); string t; getline(i, t, '!'); cout << t << i.str() << i.rdbuf(); }" 322 "Erased `char y(34);` and `char y(34);` and `<< y` and `<< y` and `<< y` and `<< y`." -- Todo: "Erased all \"char y(34);\" and all \"<< y\"." 323 324 dt "char *& f() { static char *p; cout << &p << endl; return p; } int main() { char *p = f(); cout << &p << endl; }" 325 "char *& f() { static char *p; cout << &p << ' '; return p; } int main() { char *p = f(); cout << &p; }" 326 "Replaced `<< endl` with `<< ' '`, and erased `<< endl`." -- Todo: say "first" and "last". 327 328 putStrLn "All diff tests passed." 329 where 330 dt :: String → String → String → IO () 331 dt x y r = test_cmp x r $ show $ Editing.Diff.diff x y 332 dt' :: String → String → String → String → IO () 333 dt' x y xy yx = do 334 test_cmp x xy $ show $ Editing.Diff.diff x y 335 test_cmp y yx $ show $ Editing.Diff.diff y x 336 dts :: String → [(String, String)] → IO () 337 dts _ [] = return () 338 dts s ((s', d) : r) = dt s s' d >> dts s' r 339 340make_type_tests :: IO () 341make_type_tests = do 342 t "void(pointer)" $ Right "void(T *)" 343 t "pointer to const pointer to long double" $ Right "long double*const *" 344 t "function taking an int and returning nothing" $ Right "void(int )" 345 let q = "void(int (* const (** (* const volatile (X::* volatile* (* )(int) )(char*)) [2])(long) ) [3])" in t q $ Right q 346 t "function returning nothing and taking a pointer to a function returning a bool and taking an int" $ Right "void (bool (*)(int))" 347 t "function taking a pointer to a (function returning a bool and taking an int), returning nothing" $ Right "void(bool (*)(int))" 348 t "reference to a pointer to a function returning nothing, and taking an int" $ Right "void(*&)(int)" 349 t "function taking an int, a char, a double, and returning nothing" $ Right "void(int, char, double)" 350 t "function returning nothing and taking an int, a char, and a double" $ Right "void (int, char, double)" 351 t "function returning a B<C<T>>" $ Right "B<C<T>>()" 352 t "vector<T*>" $ Right "vector<T*>" 353 t "function returning a ::B<T, (3>>2)>::value_type and taking a vector<vector<int>>" $ Right "::B<T, (3>>2)>::value_type (vector<vector<int>>)" 354 t "function taking no arguments, returning a reference to an array of three pointers to functions taking integers and returning nothing" $ Right "void(*(&())[3])(int )" 355 t "pointer to a constant volatile pointer to an array of 3 ints" $ Right "int(*volatile const *)[3]" 356 t "function returning nothing and taking a reference to an array of three pointers to void" $ Right "void (void*(&)[3])" 357 t "pointer to void(void)" $ Right "void(*)(void)" 358 t "reference to pointer to const array" $ Right "T const (*&)[]" 359 t "function taking a const (pointer to int) and a volatile function" $ Right "T (int*const , T ()volatile )" 360 t "function taking two integers, three doubles, and returning a boolean" $ Right "bool(int, int, double, double, double)" 361 t "function taking two pointers to integers" $ Right "T (int*, int*)" 362 t "rvalue reference to function" $ Right "T (&&)()" 363 t "constant constant pointer to volatile volatile int" $ Right "volatile volatile int*const " 364 --t "pointer to a function from string_bla to int" $ Right "int(*)(string_bla )" 365 t "pointer to " $ Left "Unexpected end of type description. Expected type description." 366 t "pointer to function taking pointer to function" $ Right "T (*)(T (*)())" 367 --t "pointer to int and double" $ Left "Unexpected \"a\" after \"to int \". Expected type-specifier, abstract-declarator, or end of type description." 368 t "function returning " $ Left "Unexpected end of type description. Expected type description." 369 t "function taking a pointer and a reference and returning a reference to a constant array" $ Right "T const (&(T *, T &))[]" 370 t "array of " $ Left "Unexpected end of type description. Expected type description or integer-literal." 371 t "foo bar bas" $ Left "Unexpected `bas` after `foo bar `. Expected \"::\" or template-arguments." 372 t "array of seven characters" $ Right "char[7]" 373 t "pointer to (function taking constant integer)*" $ Right "T (**)(const int)" 374 t "pointer to void()" $ Right "void(*)()" 375 t "function taking a pointer to void() returning a reference to an int[3]" $ Right "int(&(void(*)() ))[3]" 376 t "void(pointer to function)" $ Right "void(T (*)())" 377 t "function*(const int)" $ Right "T (*(const int))()" 378 t "constant pointer to a function" $ Right "T (*const )()" 379 t "(function taking an int[3] )*" $ Right "T (*)(int[3] )" 380 t "(function*[3])&()" $ Right "T (*(&())[3])()" 381 t "int(::T::U::V::**)" $ Right "int(::T::U::V::**)" 382 t "int(X::*)()const volatile" $ Right "int(X::*)()const volatile" 383 t "int volatile X::* Y::* const Z::*" $ Right "int volatile X::* Y::* const Z::*" 384{- 385 t "pointer to a member function" $ Right "void(T::*)()" 386 t "pointer to member integer" $ Right "int T::*" 387 t "pointer to member" $ Right "T T::*" 388 t "pointer to member pointer to member pointer to member array" $ Right "T(T::* T::* T::*)[]" 389-} 390 t "array*const" $ Right "T (*const)[]" 391 t "function taking (pointer to function returning int taking int) returning int" $ Right "int(int (*)(int))" 392 --t "function+" $ Left "Unexpected \"+\" after \"function\". Expected \"taking\", \"returning\", \"from\", abstract-declarator, or end of type description." 393 t "void(register pointer to string)" $ Right "void(register string*)" 394 t "array of three arrays of 2 arrays of 1 integer" $ Right "int[3][2][1]" 395 putStrLn "All make-type tests passed." 396 where 397 t :: String → Either String String → IO () 398 t i o = test_cmp i o (either (Left . id) (Right . Cxx.Show.show_simple) $ Cxx.Parse.makeType i) 399 400precedence_tests :: IO () 401precedence_tests = do 402 s "x::y" "x::y" 403 s "if (b) int *ptr = new int(3), a(2);" "if (b) {int *ptr = (new int(3));int a(2);}" 404 s "if(b) if(c) foo; else bar;" "if(b) { if(c) { foo; } else { bar; } }" 405 s "a=b<c?d=e:f=g" "a=((b<c)?(d=e):(f=g))" -- Example from TC++PL, section 6.2. 406 s "x?y?z?a:b:c:d" "x?(y?(z?a:b):c):d" 407 s "*i-40?(*i-x?S(1,*i):a)+r(i+1,e,x,a):'('+(i[1]-46?r(i+1,o-1,x,a):'.'+r(i+2,o-1,x+1,a))+')'+r(o,e,x,a)" "((*i)-40)?((((*i)-x)?(S(1,(*i))):a)+(r((i+1),e,x,a))):((('('+(((i[1])-46)?(r((i+1),(o-1),x,a)):('.'+(r((i+2),(o-1),(x+1),a)))))+')')+(r(o,e,x,a)))" -- Taken from the lambda calculus snippet. 408 s "x->x->*x.x.*x" "((x->x)->*(x.x)).*x" 409 s "x || x && x | x ^ x bitand x == x < x << x" "x || (x && (x | (x ^ (x bitand (x == (x < (x << x)))))))" 410 s "*++vector<int>{2,5,4}.rbegin()" "*(++(((vector<int>{2,5,4}).rbegin)()))" 411 s "x---------x" "((((x--)--)--)--)-x" 412 s "z+operator+(x,y)" "z+(operator+(x,y))" 413 s "x.operator()() * operator new[ ]()" "((x.operator())()) * (operator new[ ]())" 414 s "throw 2 + 1, throw, 9" "((throw (2 + 1)), throw), 9" 415 s "x + x *= x + x /= x + x" "(x + x) *= ((x + x) /= (x + x))" 416 s "(x)y + x(y)" "((x)y) + (x(y))" 417 f "(x+y)z" "Unexpected `z` after (x+y). Expected postfix operator, binary operator, ternary operator, or end of code." 418 s "a+++a, b++ +b, c+ ++c, d+++ +d, e+ +++e" "(((((a++)+a), ((b++) +b)), (c+ (++c))), ((d++)+ (+d))), (e+ (++(+e)))" 419 s "x += operatornew, b(), !c" "((x += operatornew), (b())), (!c)" 420 s "sizeof u + sizeof(x) + sizeof(y*z)" "((sizeof u) + sizeof(x)) + (sizeof(y*z))" 421 s "x.template a<int>()" "(x.template a<int>)()" 422 s "const_cast<vector<vector<int>>>(x)" "const_cast<vector<vector<int>>>(x)" -- Tricky closing angle brackets. 423 s "x.~y" "x.~y" 424 s "f (x+3,y)-g(x+3)" "(f ((x+3),y))-(g(x+3))" 425 s "::x + y::z + a::b::c::d::e" "(::x + y::z) + a::b::c::d::e" 426 s "x[y + 'z']" "x[y + 'z']" -- No parens around x + z or around 'z'. 427 f "x*" "Unexpected end of code. Expected pm-expression." 428 f "x && throw 3" "Unexpected `throw` after `x && `. Expected inclusive-or-expression." 429 f "&operator" "Unexpected end of code. Expected overloadable operator or conversion-type-id." 430 f "x.*" "Unexpected end of code. Expected cast-expression." 431 f "x--x" "Unexpected `x` after x--. Expected postfix operator, binary operator, ternary operator, or end of code." 432 f "x." "Unexpected end of code. Expected id-expression, \"template\", or pseudo-destructor-name." 433 f "x-" "Unexpected end of code. Expected multiplicative-expression." 434 f "x( " "Unexpected end of code. Expected \")\" or expression-list." 435 f "x(y" "Unexpected end of code. Expected \")\", \"(\", braced-init-list, \"::\", template-arguments, postfix operator, binary operator, ternary operator, or comma." 436 f "x?y" "Unexpected end of code. Expected colon, \"(\", braced-init-list, \"::\", template-arguments, postfix operator, binary operator, or ternary operator." 437 f "x[" "Unexpected end of code. Expected expression or braced-init-list." 438 f "x.operator foo bar()" "Unexpected `(` after `foo bar`. Expected \"::\" or template-arguments." 439 putStrLn "All precedence tests passed." 440 where 441 s :: String → String → IO () -- Test for success. 442 s i o = test_cmp i (Right o) (Cxx.Parse.precedence i) 443 f :: String → String → IO () -- Test for failure. 444 f i o = test_cmp i (Left o) (Cxx.Parse.precedence i) 445 446parse_tests :: IO () 447parse_tests = do 448 t "struct A<int>;" 449 t "void f(int, ...);" 450 t "{ if(int i = 3); }" 451 t "int (::x::y);" 452 putStrLn "All parse tests passed." 453 where 454 t :: String → IO () 455 t s = test_cmp s (Right s) $ fmap Cxx.Show.show_simple $ Cxx.Parse.parseRequest s 456 457main :: IO () 458main = do 459 basic_tests 460 Editing.EditsPreparation.use_tests 461 diff_tests 462 make_type_tests 463 precedence_tests 464 parse_tests