[gnome-nibbles/arnaudb/modernize-code] Add a test.



commit 5e9053f5f65c5054dfc11b6c29e4d56c5b2664ef
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Thu May 28 19:23:02 2020 +0200

    Add a test.
    
    This allows to check that some code
    should be refactored, and also that
    the game execution is for now a bit
    racy; both things can then improve.

 src/meson.build       |  19 +++++
 src/nibbles-game.vala |  21 ++++-
 src/nibbles-test.vala | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 268 insertions(+), 4 deletions(-)
---
diff --git a/src/meson.build b/src/meson.build
index cda95e5..623cda7 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,3 +1,22 @@
+# Tests
+
+nibbles_tests = executable(
+    'nibbles_tests',
+    [
+        'boni.vala',
+        'nibbles-game.vala',
+        'nibbles-test.vala',
+        'worm.vala',
+        'warp.vala',
+    ],
+    dependencies : [
+        gee_dep,
+        gio_dep,
+        glib_dep,
+    ]
+)
+test('nibbles-tests', nibbles_tests)
+
 # gnome-nibbles executable
 
 gnome_nibbles_sources = [
diff --git a/src/nibbles-game.vala b/src/nibbles-game.vala
index 7f0ceef..3c73133 100644
--- a/src/nibbles-game.vala
+++ b/src/nibbles-game.vala
@@ -83,11 +83,11 @@ private class NibblesGame : Object
     internal signal void animate_end_game ();
     internal signal void level_completed ();
 
-    internal NibblesGame (int tile_size, int start_level, int speed, bool fakes)
+    internal NibblesGame (int tile_size, int start_level, int speed, bool fakes, bool no_random = false)
     {
         Object (tile_size: tile_size, start_level: start_level, current_level: start_level, speed: speed, 
fakes: fakes);
 
-        Random.set_seed ((uint32) time_t ());
+        Random.set_seed (no_random ? 42 : (uint32) time_t ());
     }
 
     /*\
@@ -101,10 +101,23 @@ private class NibblesGame : Object
 
         is_running = true;
 
-        main_id = Timeout.add (GAMEDELAY * speed, main_loop_cb);
+        int worms_delay;
+        int bonus_delay;
+        switch (speed)
+        {
+            case 0: worms_delay = 7; bonus_delay = 20; break;  // used by tests
+            default:
+                if (speed > MAX_SPEED)
+                    assert_not_reached ();
+                worms_delay = GAMEDELAY * speed;
+                bonus_delay = BONUSDELAY * speed;
+                break;
+        }
+
+        main_id = Timeout.add (worms_delay, main_loop_cb);
         Source.set_name_by_id (main_id, "[Nibbles] main_loop_cb");
 
-        add_bonus_id = Timeout.add (BONUSDELAY * speed, add_bonus_cb);
+        add_bonus_id = Timeout.add (bonus_delay, add_bonus_cb);
         Source.set_name_by_id (add_bonus_id, "[Nibbles] add_bonus_cb");
     }
 
diff --git a/src/nibbles-test.vala b/src/nibbles-test.vala
new file mode 100644
index 0000000..67080c1
--- /dev/null
+++ b/src/nibbles-test.vala
@@ -0,0 +1,232 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+
+   This file is part of GNOME Nibbles.
+
+   Copyright (C) 2020 – Arnaud Bonatti <arnaud bonatti gmail com>
+
+   GNOME Nibbles is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   GNOME Nibbles is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNOME Nibbles.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+namespace NibblesTest
+{
+    private static int main (string [] args)
+    {
+        Test.init (ref args);
+        Test.add_func ("/Nibbles/test tests",
+                                 test_tests);
+        Test.add_func ("/Nibbles/test games",
+                                 test_games);
+        return Test.run ();
+    }
+
+    private static void test_tests ()
+    {
+        assert_true (1 + 1 == 2);
+    }
+
+    /*\
+    * * test games
+    \*/
+
+    private static void test_games ()
+    {
+        NibblesGame game = new NibblesGame (/* TODO tile size */ 42, /* start level */ 1, /* speed */ 0, /* 
fakes */ false, /* no random */ true);
+
+        game.numhumans = 0;
+        game.numai = 4;
+        game.create_worms ();
+
+        // FIXME adapted from nibbles-view.vala; should be in game.vala
+
+        game.boni.reset (game.numworms);
+        game.warp_manager.warps.clear ();
+
+        string tmpboard;
+        int count = 0;
+        string [] level = level_008.split ("\n");
+        for (int i = 0; i < NibblesGame.HEIGHT; i++)
+        {
+            tmpboard = level [i];
+            for (int j = 0; j < NibblesGame.WIDTH; j++)
+            {
+                game.board[j, i] = tmpboard.@get(j);
+                switch (game.board[j, i])
+                {
+                    case 'm':
+                        game.board[j, i] = NibblesGame.EMPTYCHAR;
+                        if (count < game.numworms)
+                        {
+                            game.worms[count].set_start (j, i, WormDirection.UP);
+                            count++;
+                        }
+                        break;
+                    case 'n':
+                        game.board[j, i] = NibblesGame.EMPTYCHAR;
+                        if (count < game.numworms)
+                        {
+                            game.worms[count].set_start (j, i, WormDirection.LEFT);
+                            count++;
+                        }
+                        break;
+                    case 'o':
+                        game.board[j, i] = NibblesGame.EMPTYCHAR;
+                        if (count < game.numworms)
+                        {
+                            game.worms[count].set_start (j, i, WormDirection.DOWN);
+                            count++;
+                        }
+                        break;
+                    case 'p':
+                        game.board[j, i] = NibblesGame.EMPTYCHAR;
+                        if (count < game.numworms)
+                        {
+                            game.worms[count].set_start (j, i, WormDirection.RIGHT);
+                            count++;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        for (int i = 0; i < NibblesGame.HEIGHT; i++)
+        {
+            for (int j = 0; j < NibblesGame.WIDTH; j++)
+            {
+                switch (game.board[j, i])
+                {
+                    case '.': // empty space
+                        game.board[j, i] = 'a';
+                        break;
+                    case 'Q':
+                    case 'R':
+                    case 'S':
+                    case 'T':
+                    case 'U':
+                    case 'V':
+                    case 'W':
+                    case 'X':
+                    case 'Y':
+                    case 'Z':
+                        game.warp_manager.add_warp (game.board, j - 1, i - 1, -(game.board[j, i]), 0);
+                        break;
+                    case 'r':
+                    case 's':
+                    case 't':
+                    case 'u':
+                    case 'v':
+                    case 'w':
+                    case 'x':
+                    case 'y':
+                    case 'z':
+                        game.warp_manager.add_warp (game.board, -(game.board[j, i] - 'a' + 'A'), 0, j, i);
+                        game.board[j, i] = NibblesGame.EMPTYCHAR;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        // END FIXME
+
+        assert_true (game.numworms == 4);
+        assert_true (game.worms.size == 4);
+
+        // as there is no random, this output should be regular; it is not, surely because relying on two 
timeouts is racy
+        game.bonus_applied.connect ((bonus, worm) => { Test.message (@"worm $(worm.id) took bonus at 
[$(bonus.x), $(bonus.y)]"); });
+
+        game.add_worms ();
+        game.start (/* add initial bonus */ true);
+
+        assert_true (game.worms.@get (0).head.x ==  4 && game.worms.@get (0).head.y == 14);
+        assert_true (game.worms.@get (1).head.x == 18 && game.worms.@get (1).head.y == 31);
+        assert_true (game.worms.@get (2).head.x ==  9 && game.worms.@get (2).head.y == 39);
+        assert_true (game.worms.@get (3).head.x == 51 && game.worms.@get (3).head.y == 45);
+
+        // run until game is finished; takes between 4 and 12 seconds on my computer, depending on worms 
motivation
+        bool completed = false;
+        game.level_completed.connect (() => { completed = true; });
+        MainContext context = MainContext.@default ();
+        while (!completed)
+            context.iteration (/* may block */ false);
+    }
+
+    private const string level_008 = 
"fccccccccccccccccccccccccccccccccccccccce........dcccccccccccccccccccccccccccccccccccccccccg"
+                            + "\n" + 
"b..........................................................................................b"
+                            + "\n" + 
"b..........................................................................................b"
+                            + "\n" + 
"b..........................................................................................b"
+                            + "\n" + 
"b...R...............................fg...........................fg.....................S..b"
+                            + "\n" + 
"b...u...............................dlg..........................bb....................t...b"
+                            + "\n" + 
"b....................................dlg.........................bb........................b"
+                            + "\n" + 
"b...........fg........................dlg........................bb........................b"
+                            + "\n" + 
"b...........bb.........................dlg.......................bb........................b"
+                            + "\n" + 
"b...o.......bb..........................dlg......................bb........................b"
+                            + "\n" + 
"b...........bb...........................dlg.....................bb...fccccccccg...........b"
+                            + "\n" + 
"b...........bb............................dlg....................bb...dcccccccclg..........b"
+                            + "\n" + 
"b...........bb.............................dlg...................bb............dlg.........b"
+                            + "\n" + 
"b...........bb..............................dlg..................bb.............dlg........b"
+                            + "\n" + 
"b...........bb............fg.................dlg.................bb..............dlccg.....b"
+                            + "\n" + 
"b...........bb...........fle..................dlg................bb...............dcce.....b"
+                            + "\n" + 
"b...........bb..........fle....................dlg...............bb........................b"
+                            + "\n" + 
"e...........de.........fle......................dlg..............bb........................d"
+                            + "\n" + 
"......................fle........................dlg.............bb........................."
+                            + "\n" + 
".....................fle.........................fle.............bb........................."
+                            + "\n" + 
"....................fle.........................fle..............bb........................."
+                            + "\n" + 
"...................fle.........................fle...............bb........................."
+                            + "\n" + 
"..................fle.........................fle................bb......fg................."
+                            + "\n" + 
"..................de.........................fle.................bb......dlg................"
+                            + "\n" + 
"............................................fle..................bb.......dlg..............."
+                            + "\n" + 
"............................................dlg..................bb........dlg.............."
+                            + "\n" + 
"g.................o..........................dlg.................bb.........dlg............f"
+                            + "\n" + 
"b.............................................dlg................bb..........dlg...........b"
+                            + "\n" + 
"b..............................................dlg...............bb...........dlg..........b"
+                            + "\n" + 
"b........fg.....................fg..............dlg..............bb............de..........b"
+                            + "\n" + 
"b........bb.....................dlg..............dlg.............bb........................b"
+                            + "\n" + 
"b........bb......................dlg..............dlg............bb........................b"
+                            + "\n" + 
"b........bb.......................dlg..............dlg...........bb........................b"
+                            + "\n" + 
"b........bb........................dlg..............de...........bb........................b"
+                            + "\n" + 
"b........bb.........................dlg..........................bb........................b"
+                            + "\n" + 
"b........bdcccccccg..................dlg.........................bb........................b"
+                            + "\n" + 
"b........dcccccccce...................dlg........................bb........................b"
+                            + "\n" + 
"b......................................dlg.......................bb........................b"
+                            + "\n" + 
"b.......................................dlg......................bb....fcccccccccccccg.....b"
+                            + "\n" + 
"b...p....................................dlg.....................bb....dccccccccccccce.....b"
+                            + "\n" + 
"b........................................fle.....................bb........................b"
+                            + "\n" + 
"b.......................................fle......................bb........................b"
+                            + "\n" + 
"b.................fg...................fle.......................bb........................b"
+                            + "\n" + 
"b.................bb..................fle........................bb........................b"
+                            + "\n" + 
"b...........fg....bb.................fle.........................bb........................b"
+                            + "\n" + 
"b..........fle....bb................fle..........................bb........................b"
+                            + "\n" + 
"b.........fle.....bb...............fle...........................bb........................b"
+                            + "\n" + 
"b........fle......bb...............de............................bb........................b"
+                            + "\n" + 
"b.......fle.......bb.............................................bb........................b"
+                            + "\n" + 
"b......fle........bb.............................................bb........................b"
+                            + "\n" + 
"b......de.........bb...............................m.............bb........................b"
+                            + "\n" + 
"b.................bb.............................................bb........................b"
+                            + "\n" + 
"b.................bb.............................................bb........................b"
+                            + "\n" + 
"b.................bb.............................................bdcccccccccccccg..........b"
+                            + "\n" + 
"b.................bb............fccccccccccccccccccccccg.........dcccccccccccccce..........b"
+                            + "\n" + 
"b.................bb............dcccccccccccccccccccccce...................................b"
+                            + "\n" + 
"b.................bb.......................................................................b"
+                            + "\n" + 
"b.................bb...................................................................n...b"
+                            + "\n" + 
"b.................bb.......................................................................b"
+                            + "\n" + 
"b.................bb......................n................................................b"
+                            + "\n" + 
"b...s.............bb...................................................................r...b"
+                            + "\n" + 
"b.................de.......................................................................b"
+                            + "\n" + 
"b...T...................................................................................U..b"
+                            + "\n" + 
"b..........................................................................................b"
+                            + "\n" + 
"b..........................................................................................b"
+                            + "\n" + 
"dcccccccccccccccccccccccccccccccccccccccg........fccccccccccccccccccccccccccccccccccccccccce";
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]