חזור לתיקייה: wet

tests_matamvidia_extra

חיפוש בתיקיה
Ctrl K
לחץ כאן או הקש Ctrl K כדי לחפש בכל התיקיה

    tests_matamvidia_extra

    02340124

    מבוא לתכנות מערכות

    רשימות הרצאה לקריאה בשבת

    tests_matamvidia_extra

    הופק מתוך תקיית התואר של שקד

    uni-folder.vercel.app

    tests-matamvidia-extra.cpp

    הערה (קובץ קוד)

    קובץ זה הוא קובץ קוד מסוג CPP.

    #include "tests_matamvidia_extra.h"
    #include <iostream>
    #include <sstream>
    #include <string>
    #include "Matrix.h"
    #include "MataMvidia.h"
    
    using namespace std;
    
    // ─── Test infrastructure ─────────────────────────────────────────────────────
    
    static int passed = 0, failed = 0;
    
    #define CHECK(label, expr)                                              \
        do {                                                                \
            if (expr) {                                                     \
                std::cout << "  [PASS] " << label << "\n";                  \
                ++passed;                                                   \
            } else {                                                        \
                std::cout << "  [FAIL] " << label                          \
                          << "  (" << __FILE__ << ":" << __LINE__ << ")\n";\
                ++failed;                                                   \
            }                                                               \
        } while (0)
    
    int getCounterPassed()
    {
        return passed;
    }
    
    int getCounterFailed()
    {
        return failed;
    }
    
    // ─── Helpers ─────────────────────────────────────────────────────────────────
    
    static Matrix make2x2(int a, int b, int c, int d) {
        Matrix m(2, 2);
        m(0,0)=a; m(0,1)=b;
        m(1,0)=c; m(1,1)=d;
        return m;
    }
    
    static Matrix make3x3(int a,int b,int c,int d,int e,int f,int g,int h,int k) {
        Matrix m(3,3);
        m(0,0)=a; m(0,1)=b; m(0,2)=c;
        m(1,0)=d; m(1,1)=e; m(1,2)=f;
        m(2,0)=g; m(2,1)=h; m(2,2)=k;
        return m;
    }
    
    static MataMvidia make_movie(const string& name, const string& author, int n) {
        Matrix* arr = new Matrix[n];
        for (int i = 0; i < n; i++)
            arr[i] = make2x2(i+1, i+2, i+3, i+4);
        MataMvidia mv(name, author, arr, n);
        delete[] arr;
        return mv;
    }
    
    // ─── Tests ───────────────────────────────────────────────────────────────────
    
    // 1. Frames are stored in order, not reversed or shuffled
    void test_frame_order_preserved() {
        cout << "\n[Frame Order Preserved]\n";
    
        Matrix arr[5];
        for (int i = 0; i < 5; i++)
            arr[i] = make2x2(i*100, i*100, i*100, i*100);
    
        MataMvidia mv("Order","Test", arr, 5);
        bool ok = true;
        for (int i = 0; i < 5; i++)
            if (mv[i] != arr[i]) { ok = false; break; }
        CHECK("all 5 frames in correct order", ok);
    }
    
    // 2. Constructing with different frame sizes (1x1, 2x2, 3x3)
    void test_mixed_frame_sizes() {
        cout << "\n[Mixed Frame Sizes]\n";
    
        Matrix f1(1,1,7);
        Matrix f2 = make2x2(1,2,3,4);
        Matrix f3 = make3x3(9,8,7, 6,5,4, 3,2,1);
    
        Matrix arr[3] = { f1, f2, f3 };
        MataMvidia mv("Mixed","A", arr, 3);
    
        CHECK("1x1 frame stored", mv[0] == f1);
        CHECK("2x2 frame stored", mv[1] == f2);
        CHECK("3x3 frame stored", mv[2] == f3);
    }
    
    // 3. Copy constructor: modifying original after copy doesn't affect copy
    void test_copy_ctor_independence_both_ways() {
        cout << "\n[Copy Independence Both Ways]\n";
    
        MataMvidia original = make_movie("Orig","Dir",3);
        MataMvidia copy(original);
    
        original[0](0,0) = 9999;
        CHECK("copy unaffected by original mutation", copy[0](0,0) != 9999);
    
        copy[1](0,0) = 8888;
        CHECK("original unaffected by copy mutation", original[1](0,0) != 8888);
    }
    
    // 4. Assignment operator: chained assignment  a = b = c
    void test_chained_assignment() {
        cout << "\n[Chained Assignment]\n";
    
        MataMvidia a = make_movie("A","x",2);
        MataMvidia b = make_movie("B","y",3);
        MataMvidia c = make_movie("C","z",4);
    
        a = b = c;
        CHECK("a == c after chained assign (frame 0)", a[0] == c[0]);
        CHECK("b == c after chained assign (frame 3)", b[3] == c[3]);
    
        c[0](0,0) = 42;
        CHECK("a independent of c after chained assign", a[0](0,0) != 42);
    }
    
    // 5. operator+= with movie doesn't alter the argument movie
    void test_append_movie_doesnt_alter_argument() {
        cout << "\n[+= Movie: Argument Unchanged]\n";
    
        MataMvidia mv1 = make_movie("M1","A",2);
        MataMvidia mv2 = make_movie("M2","B",3);
    
        Matrix before0 = mv2[0];
        Matrix before2 = mv2[2];
    
        mv1 += mv2;
    
        CHECK("mv2[0] unchanged after mv1 += mv2", mv2[0] == before0);
        CHECK("mv2[2] unchanged after mv1 += mv2", mv2[2] == before2);
    }
    
    // 6. operator+ doesn't alter either argument
    void test_plus_doesnt_alter_arguments() {
        cout << "\n[operator+: Arguments Unchanged]\n";
    
        MataMvidia mv1 = make_movie("A","x",2);
        MataMvidia mv2 = make_movie("B","y",2);
    
        Matrix f1_0 = mv1[0], f2_0 = mv2[0];
        MataMvidia result = mv1 + mv2;
    
        CHECK("mv1[0] unchanged after +", mv1[0] == f1_0);
        CHECK("mv2[0] unchanged after +", mv2[0] == f2_0);
    }
    
    // 7. operator+ result has correct total length
    void test_plus_result_length() {
        cout << "\n[operator+: Result Length]\n";
    
        MataMvidia mv1 = make_movie("A","x",3);
        MataMvidia mv2 = make_movie("B","y",5);
        MataMvidia result = mv1 + mv2;
    
        // Access all 8 frames — if length is wrong this will exit()
        bool ok = true;
        for (int i = 0; i < 8; i++) {
            // just access, don't crash
            (void)result[i];
        }
        CHECK("all 8 frames accessible in result", ok);
        // Verify frame content order
        CHECK("result[0] == mv1[0]", result[0] == mv1[0]);
        CHECK("result[3] == mv2[0]", result[3] == mv2[0]);
        CHECK("result[7] == mv2[4]", result[7] == mv2[4]);
    }
    
    // 8. Appending a movie to itself (self-concatenation)
    void test_self_append() {
        cout << "\n[Self-Append (mv += mv)]\n";
    
        MataMvidia mv = make_movie("Self","S",3);
        Matrix f0 = mv[0];
        Matrix f2 = mv[2];
    
        mv += mv;
    
        CHECK("self-append: frame 0 unchanged", mv[0] == f0);
        CHECK("self-append: frame 3 == old frame 0", mv[3] == f0);
        CHECK("self-append: frame 5 == old frame 2", mv[5] == f2);
    }
    
    // 9. Multiple sequential += frame calls
    void test_sequential_frame_appends() {
        cout << "\n[Sequential Frame Appends]\n";
    
        Matrix single[1] = { make2x2(0,0,0,0) };
        MataMvidia mv("Seq","A", single, 1);
    
        Matrix frames[10];
        for (int i = 0; i < 10; i++) {
            frames[i] = make2x2(i, i*2, i*3, i*4);
            mv += frames[i];
        }
    
        bool ok = true;
        for (int i = 0; i < 10; i++)
            if (mv[i+1] != frames[i]) { ok = false; break; }
        CHECK("all 10 sequentially appended frames correct", ok);
    }
    
    // 10. Multiple sequential += movie calls
    void test_sequential_movie_appends() {
        cout << "\n[Sequential Movie Appends]\n";
    
        MataMvidia base = make_movie("Base","X",1);
    
        for (int i = 0; i < 5; i++) {
            MataMvidia extra = make_movie("Extra","Y",2);
            base += extra;
        }
    
        // Should now have 1 + 5*2 = 11 frames
        CHECK("frame 1 correct (first extra, batch 0)", base[1](0,0) == 1);
        CHECK("frame 10 correct (last extra, batch 4)", base[10](0,0) == 2);
    }
    
    // 11. operator+ chained: (a + b) + c
    void test_chained_plus() {
        cout << "\n[Chained operator+]\n";
    
        MataMvidia a = make_movie("A","x",2);
        MataMvidia b = make_movie("B","y",2);
        MataMvidia c = make_movie("C","z",2);
    
        MataMvidia result = a + b + c;
    
        CHECK("chained +: frame 0 from a", result[0] == a[0]);
        CHECK("chained +: frame 2 from b", result[2] == b[0]);
        CHECK("chained +: frame 4 from c", result[4] == c[0]);
        CHECK("chained +: frame 5 from c", result[5] == c[1]);
    }
    
    // 12. Non-const operator[] allows in-place modification
    void test_nonconst_index_mutation() {
        cout << "\n[Non-const [] Mutation]\n";
    
        MataMvidia mv = make_movie("M","A",3);
        mv[1](0,0) = 42;
        mv[1](1,1) = 99;
    
        CHECK("mutation via [] persists (0,0)", mv[1](0,0) == 42);
        CHECK("mutation via [] persists (1,1)", mv[1](1,1) == 99);
        CHECK("other frames unaffected", mv[0](0,0) == 1 && mv[2](0,0) == 3);
    }
    
    // 13. Const movie: const [] returns correct value
    void test_const_index_access() {
        cout << "\n[Const [] Access]\n";
    
        Matrix arr[2] = { make2x2(10,20,30,40), make2x2(50,60,70,80) };
        const MataMvidia mv("C","D", arr, 2);
    
        CHECK("const [0](0,0)", mv[0](0,0) == 10);
        CHECK("const [0](1,1)", mv[0](1,1) == 40);
        CHECK("const [1](0,0)", mv[1](0,0) == 50);
        CHECK("const [1](1,1)", mv[1](1,1) == 80);
    }
    
    // 14. Output: correct number of frames printed
    void test_output_frame_count() {
        cout << "\n[Output: Frame Count]\n";
    
        MataMvidia mv = make_movie("CountTest","Author",4);
        std::ostringstream oss;
        oss << mv;
        string s = oss.str();
    
        CHECK("output contains Frame 0", s.find("Frame 0") != string::npos);
        CHECK("output contains Frame 1", s.find("Frame 1") != string::npos);
        CHECK("output contains Frame 2", s.find("Frame 2") != string::npos);
        CHECK("output contains Frame 3", s.find("Frame 3") != string::npos);
        CHECK("output does NOT contain Frame 4", s.find("Frame 4") == string::npos);
    }
    
    // 15. Output format: movie name with spaces, author with spaces
    void test_output_names_with_spaces() {
        cout << "\n[Output: Names With Spaces]\n";
    
        Matrix arr[1] = { make2x2(1,2,3,4) };
        MataMvidia mv("The Great Movie","John Doe", arr, 1);
        std::ostringstream oss;
        oss << mv;
        string s = oss.str();
    
        CHECK("full movie name in output", s.find("The Great Movie") != string::npos);
        CHECK("full author name in output", s.find("John Doe") != string::npos);
    }
    
    // 16. Expansion: frames survive across multiple expandArray calls
    void test_expansion_data_integrity() {
        cout << "\n[Expansion: Data Integrity Across Grows]\n";
    
        Matrix arr[1] = { make2x2(77, 88, 99, 11) };
        MataMvidia mv("Grow","Test", arr, 1);
    
        // Default EXPANSION_RATE=8, so append 100 frames to force ~12 expansions
        for (int i = 0; i < 100; i++)
            mv += make2x2(i, i, i, i);
    
        CHECK("original frame[0] survives 100 appends", mv[0] == arr[0]);
        CHECK("frame[1] correct after expansion", mv[1](0,0) == 0);
        CHECK("frame[50] correct after expansion", mv[50](0,0) == 49);
        CHECK("frame[100] correct after expansion", mv[100](0,0) == 99);
    }
    
    // 17. Appending 1-frame movie to another 1-frame movie
    void test_single_frame_movies_combined() {
        cout << "\n[Single-frame Movies Combined]\n";
    
        Matrix a1[1] = { make2x2(1,1,1,1) };
        Matrix a2[1] = { make2x2(2,2,2,2) };
        MataMvidia mv1("One","A", a1, 1);
        MataMvidia mv2("Two","B", a2, 1);
    
        MataMvidia result = mv1 + mv2;
        CHECK("combined[0] == mv1[0]", result[0] == a1[0]);
        CHECK("combined[1] == mv2[0]", result[1] == a2[0]);
    }
    
    // 18. Appended frames reference correct matrix values, not aliased
    void test_appended_frame_not_aliased() {
        cout << "\n[Appended Frame Not Aliased]\n";
    
        MataMvidia mv = make_movie("M","A",1);
        Matrix extra = make2x2(5,5,5,5);
        mv += extra;
    
        extra(0,0) = 123;  // mutate original
        CHECK("appended frame not aliased to source", mv[1](0,0) == 5);
    }
    
    // 19. operator+ result is independent of both sources
    void test_plus_result_independent() {
        cout << "\n[operator+: Result Independent of Sources]\n";
    
        MataMvidia mv1 = make_movie("A","x",2);
        MataMvidia mv2 = make_movie("B","y",2);
        MataMvidia result = mv1 + mv2;
    
        mv1[0](0,0) = 555;
        mv2[0](0,0) = 666;
    
        CHECK("result[0] unaffected by mv1 mutation", result[0](0,0) != 555);
        CHECK("result[2] unaffected by mv2 mutation", result[2](0,0) != 666);
    }
    
    // 20. Many movies concatenated via operator+
    void test_many_movies_concatenated() {
        cout << "\n[Many Movies Concatenated]\n";
    
        MataMvidia result = make_movie("Base","X",1);
        for (int i = 0; i < 9; i++)
            result = result + make_movie("Extra","Y",1);
    
        bool ok = true;
        for (int i = 0; i < 10; i++)
            (void)result[i];  // must not crash
        CHECK("10 movies concatenated: all frames accessible", ok);
        CHECK("frame 0 value correct", result[0](0,0) == 1);
        CHECK("frame 9 value correct", result[9](0,0) == 1);
    }