Skip to content

Commit

Permalink
Merge pull request #50 from seeseemelk/docs/improve-docs
Browse files Browse the repository at this point in the history
Add old documentation to new format
  • Loading branch information
seeseemelk committed Apr 19, 2020
2 parents 90125e2 + 44d6517 commit 40843d7
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 2 deletions.
4 changes: 4 additions & 0 deletions docs/dependencies.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Dependencies
============
.. warning::
This section is about a feature that has not yet been merged.
37 changes: 37 additions & 0 deletions docs/entity_mock.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Mock Entities
=============
The EntityMock adds several methods that can be used be on all entities created by MockBukkit.

This will check that the entity is within a certain distance from the location.
::
entity.assertLocation(location, distance);

You can also assert that a player was teleported by a plugin.
::
entity.assertTeleported(location, distance);
entity.assertNotTeleported();

If you want to reset the teleported flag you can use
::
entity.clearTeleported();

This will useful if you know that a method teleports your entity and you want to check if afterwards a different method *doesn't* teleport it.

To check if the entity was teleported without throwing AssertionExceptions use:
::
if (entity.hasTeleported())
{
// Player was teleported
}

In normal bukkit the only way to move an entity is by teleporting it, but this causes a teleported event.
Therefore MockBukkit adds a setter for the location
::
entity.setLocation(location);

In MockBukkit an entity can also be renamed if needed
::
entity.setName("new-name");

An EntityMock also implements the [MessageTarget](MessageTarget.md) interface so one can test received messages.

79 changes: 79 additions & 0 deletions docs/first_tests.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
First Tests
===========

The First Test
--------------
In order to start testing, you will need a directory to contain your tests.
This directory will most often be in ``src/test``, next to ``src/main``.

For instance, if you have a class at ``src/main/com/github/username/MyPlugin.java``,
you would probably put unit tests for this class at
``src/test/com/github/username/MyPluginTests.java``.

Extra Constructor
^^^^^^^^^^^^^^^^^
Before you can start running unit tests, your plugin will need an extra constructor.
This is because the ``JavaPlugin`` class expects that the plugin was loaded by a
special class loader.
However, it is not possible to use this class loader during the unit test phase.

The workaround is easy though, a constructor with a visibility of ``protected``.

::
public class MyPlugin extends JavaPlugin {
public MyPlugin() {
super();
}

protected MyPlugin(JavaPluginLoader loader, PluginDescriptionFile descriptionFile, File dataFolder, File file) {
super(loader, descriptionFile, dataFolder, file);
}

@Override
public void onEnable() {
// Executed when your plugin is enabled.
}

@Override
public void onDisable() {
// Executed when your plugin is disabled.
}
}

Creating the Test Class
^^^^^^^^^^^^^^^^^^^^^^^
Once your directories are set up, you can create unit tests like this:
::
public class MyPluginTests {
private ServerMock server;
private MyPlugin plugin;

@Before
public void setUp() {
// Start the mock server
server = MockBukkit.mock();
// Load your plugin
plugin = MockBukkit.load(MyPlugin.class);
}

@After
public void tearDown() {
// Stop the mock server
MockBukkit.unmock();
}

@Test
public void thisTestWillFail() {
// Perform your test
}
}

UnimplementationOperationException
----------------------------------
Sometimes your code may use a method that is not yet implemented in MockBukkit.
When this happens MockBukkit will, instead of returning placeholder values, throw
an ``UnimplementedOperationException``.
These exception extends ``AssumationException`` and will cause the test to be skipped.

These exceptions should just be ignored, though pull requests that add functionality
to MockBukkit are always welcome!
67 changes: 65 additions & 2 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
Getting Started
===============

Before MockBukkit can be used, a dependency has to be added to your build tool.
In order to use MockBukkit, you first have to integrate it into your build tool.
You will also need to know which version of MockBukkit to use.
MockBukkit version numbering can be a little bit confusing.
The most important thing to remember is that each version of MockBukkit is named
after the version of Bukkit it implements, followed by the version number of
MockBukkit itself.

For instance: MockBukkit-v1.15 v0.3.0 is the 0.3.0 release of MockBukkit,
targetting plugins build for Minecraft 1.15.
The latest stable version can always be found at https://search.maven.org/search?q=MockBukkit

Gradle
------
If you're using Gradle, add the following to your `build.gradle` file:
If you are using Gradle, you will need to setup your `build.gradle` file to enable
unit testing.

Dependencies
^^^^^^^^^^^^
To enable unit testing, all you need to do is add the JUnit dependency and the
correct MockBukkit dependency.
Here is an example which adds support for JUnit 4.12 and MockBukkit-v1.15:
::

repositories {
Expand All @@ -17,3 +32,51 @@ If you're using Gradle, add the following to your `build.gradle` file:
testImplementation 'junit:junit:4.12'
testImplementation 'com.github.seeseemelk:MockBukkit-v1.15:0.3.0-SNAPSHOT'
}

Running
^^^^^^^
When this has been added, you can run your tests using the `test` task.
For Windows, running the following command will execute the tests:
::
gradlew.bat test
On Linux and macOS, use the following command:
::
./gradlew test

Maven
-----
For people that use Maven instead of Gradle can also use MockBukkit by adding it
to their `pom.xml`.
To do so, both JUnit and MockBukkit habe to be added to your dependencies:
::
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.15</artifactId>
<version>0.3.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<!-- Add your other dependencies here -->
</dependencies>

<build>
<pluginManagement>
<plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>

Running
^^^^^^^
After having modified your `pom.xml`, you can run the unit tests as follows:
::
mvn test
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ testing of plugins that use timers or delays.
:caption: Contents

getting_started.rst
first_tests.rst
player_mock.rst
world_mock.rst
scheduler_mock.rst
entity_mock.rst
message_target.rst
dependencies.rst

19 changes: 19 additions & 0 deletions docs/message_target.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
MessageTarget introduction
==========================
The MessageTarget interface is a small interface implemented by methods that can receive messages.
Two examples of message targets are ```ConsoleCommandSenderMock``` and ```EntityMock```.

Using MessageTarget
-------------------
Any message that was sent to the target can be read using
::
SimpleEntityMock entity = new SimpleEntityMock();
entity.sendMessage("Hello world!");
String message = entity.nextMessage();

It also contains two assert methods to check if a message was or wasn't received.
::
entity.sendMessage("Hello world!");
entity.assertSaid("Hello world!");
entity.assertNoMoreSaid();

32 changes: 32 additions & 0 deletions docs/player_mock.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Adding a player
===============
MockBukkit has several methods to add player to the test server.

This method creates a random new player and lets it join the server.
::
PlayerMock player = server.addPlayer();

If you want to customise the object before adding it (such as setting a user name), this can be used:
::
PlayerMock player = server.addPlayer(player)
One can also add a UUID after the username if needed.

And lastly, if you want to add a whole bunch of players quickily, consider using:
::
server.setPlayers(20);
This will add 20 players to the server.
After this command you can use ```server.getPlayer(index)``` to reference each player in an easy way.

# PlayerMock methods
The PlayerMock class adds several methods that makes unit testing player related methods nicer.
In all examples we will assume that your unit test starts with:
::
PlayerMock player = server.addPlayer();

It's possible to assert that a player is in a specific gamemode.
If the player is not in that gamemode, an AssertionException is thrown.
::
player.assertGameMode(GameMode.SURVIVAL);

PlayerMock extends [EntityMock](EntityMock.md) since it's possible to use those added methods too.

23 changes: 23 additions & 0 deletions docs/scheduler_mock.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Mock Scheduler (Testing Timers and Delays)
==========================================
MockBukkit allows the testing of timers and delays that are normally created using the Bukkit scheduler.
This schedulers is used in the same way as a normal scheduler except that it adds several extra methods.

Executing ticks
---------------
The scheduler can be asked to perform a single tick during tick.
::
server.getScheduler().performOneTick();

If more ticks need to be executed in quick succession, it's possible to execute many ticks at once.
The following code will perform a hundred ticks.
::
server.getScheduler().performTicks(100L);

Using this method executes all ticks in order, as if they were executed on a real server.

Getting the current tick.
-------------------------
MockBukkit has an extra method that allows to get the number of ticks since MockBukkit was last started.
::
long tick = server.getScheduler().getCurrentTick();
12 changes: 12 additions & 0 deletions docs/world_mock.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Creating a mock World
=====================
Often times one needs to interact with the minecraft world.
MockBukkit always the creation of superflat worlds on the fly.
Each block in the world is generated the moment it is accessed for the first time, so creation new worlds is a very cheap operation.

The following code will create a flat world:
::
WorldMock = server.addSimpleWorld("my_world");

Every time MockBukkit is started a world called "world" is automatically created.
All players are also added to this default world.

0 comments on commit 40843d7

Please sign in to comment.