I really want to grasp TDD approach and integrate it into my coding behaviors, but I have really hard time to understand how do people test some complicated cases. For example, consider this situation: I have a game, consisting of levels. When the user passes the level, I should display a dialog, informing him of his current position amongst his friends. The dialog can show only 3 places, amongst which the current user should have the highest place and score. If the user has less than 2 friends, I must display "fake" friends in this dialog.
So, I have a function, which receives a vector of objects, containing UIDs of users (by which they are represented in some social network) and their scores and places in the leaderboard for the given level. The function should be called after the game level ends and it should marshal those users in right order in the dialog (view) which displays the users in proper order, according to their place, scores etc. So this function looks like this in pseudocode:
public function marshallUsers(users:Vector.<User>):void {
// Add necessary fake users, if the vector length less than 3
// Compute social network request for users's photos
// basically it just a string with comma-separated user ids
// Enquiry social network API asynchronously, calling callback
// function when the request succeeds. This is singleton.
}
private function callback(users:Array):void
{
// fill the user portraits in the dialog
}
So how can I extract what exactly should I test in the marshallUsers function? Inner object state changes? How can I test the function which not only relies on external global object, but also logically continues after the asynchronous call succeeds? How can I avoid that?
If your case is "too complicated" that is often because it is too broad.
From your description, marshallUsers doesn't really seem to perform much logic internally (except perhaps adding fake friends?). It just calls a sequence of other objects? If so then there isn't much to test. You should be testing the individual components that marshallUsers calls upon in their own tests.
What you could be testing is whether marshallUsers correctly handles various output states from each of the components it uses (such as a valid set of users, less than 3 users, unable to get a response etc). You would mock the various components to provide these dummy responses.
Remember, you are ideally only testing the logic within marshallUsers, everything else should be isolated from it.
For what it's worth, in the tests we do for similar cases to yours, we do them firstly as I have described, but then normally also have at least one "end-to-end" test which calls an API just to make sure it all fits together correctly. The argument is of course that with well thought out tests you shouldn't need to - but the real world is not always well thought out.
Related
I have been trying to understand how actor model and web workers work.
In https://dzone.com/articles/html5-web-workers-classic:
"Web Workers provide a message-passing model, where scripts can communicate only through well-defined immutable messages, do not share any data, and do not use synchronization mechanisms for signaling or data integrity."
To me, it sounds very similar to actor model. Is there a difference?
UPDATE:
According to Benjamin Erb:
" The fundamental idea of the actor model is to use actors as concurrent primitives that can act upon receiving messages in different ways:
1.Send a finite number of messages to other actors.
2. Spawn a finite number of new actors.
3. Change its own internal behavior, taking effect when the next incoming message is handled."
The first two apply, but how about the last one?
Yes, actor model quite describes how do the workers work. However actor model has some more abstract requirements that also depend on your implementation - but I recommend complying with the actor model. You can read the full article on Wikipedia.
There's one thing I'd like to point out to you though:
No requirement on order of message arrival
This is something that depends on your implementation and I strongly recommend to comply with this requirement. This means, for example, if sending data in chunks, give chunks indexes. Worker messages arrive in the order they're sent, but it's good not to rely on that once your code becomes complicated.
Change its own internal behavior, taking effect when the next incoming message is handled (as per your "update")
This point kinds conflicts with the previous one. But anyone who at least read some web workers tutorial, the answer is obvious: Yes, worker can do that. Consider following code:
var name = "Worker";
self.addEventListener("message", (e)=>{
if(typeof e.data.newName=="string") {
name = e.data.newName;
}
if(e.data.command == "sendName") {
self.postMessage({myName: name});
}
});
Needless to say, if you send new name to the worker, the response to the "sendName" messages will be different from that point. Such change to behaviour is trivial, but can be arbitrarily complex.
If you're interested in actor model also see javascript implementation Vert.x.
Note: there are ways to block between Workers, but those are hacks and are not intended. One I can think of is asynchronous XHR with server holding the lock. I don't think this counts as exception of actor model.
Lets say you have a set of resources which look like:
/v1/API/Events
/v1/API/Transactions
where Events look like:
{
"id":1,
"name":"blah",
"date":"2010-01-11",
"duration":1231231,
"transaction_id":3
}
except that the transaction_id can be left out or set to null
Transactions look like:
{
"id":1,
"name":"transaction_name",
"date":"2015-01-01"
}
Now here is the issue, there are some times where it would be beneficial to be able to get a Tranaction and it's events at the same time. It would definitely be beneficial to be able to POST a Transaction with it's events. i.e.
{
"name":"new_transaction_one",
"events": [
{
"name":"blob",
"date":"2010-01-01,
"duration":10
},
{
"name":"blob_2",
"date":"2010-01-010,
"duration":15
},
]
and it would also be useful to be able to make a GET request like:
/v1/API/Transactions/1?withEvents=Y
Other options would be to have another resource:
/v1/API/TransactionsWithEvents
But if you have objects with several different sets of child records, you would have to have a lot of different combinations. I also don't like that they have different paths event though we are talking about the same resource.
I'm leaning towards using query parameters in the GET request but I'm wondering if there are any gotchas.
Here is a case where typical RESTful API scaffolding reaches it's limits. It would probably be preferable to create some convenience methods (especially for POST) that can work across the different resources, for example, creating a transaction and associated events in a single POST. You will find that most any service with a relative level of complexity needs to have the convenience methods to prevent the user from having to (using same example) create the transaction, read the transaction id from response, then create events, then create transaction to event relations.
Tying it back to your example, that may mean you have a method like
POST /v1/API/CreateTransactionWithEvents
You may not need similar convenience endpoint for the case of returning events with transactions, as I think your parameter string approach may make sense here since you are just enriching the data returned from the record with related events.
GET /v1/API/Transactions/{ID}?withEvents=1
This is a bit more of a gray area and really subject to what works best within your other API's (so you are not doing something totally different), with providing clear API to clients, etc.
Just think of typical resource-related endpoints (i.e for Transactions and Events) as the main backbone for your RESTful service, with adding convenience methods as appropriate to address specific resource CRUD use cases that are not easily handled by backbone endpoints. This could be cases where you want to prevent client from making a series of API calls to get to something you might provide in a single call, or when you need to do something like atomically added records across resources with a single API call.
I'm fairly new to multiplayer design and am struggling to find the information i need to continue in my synchronous (you cannot disconnect and continue at a later time similar to hearthstone), turn-based, pvp "card" game. I'm using AS3 (flash) as my client side and node.js with javascript + mysql for the server-side processing.
In this game, the cards are created by the players themselves. It's importnat to note that these "cards" are assembled from individual building blocks (library swf files); The database keeps track of how these cards are made/assembled. Because there can be hundreds of uniqely made cards per player, i need a good way to load information about these on demand for pvp battles or for modding/deck building purposes.
What i've accomplished so far:
i have successfully sent data to server and sent data back to flash over an XMLSocket.
I have successfully assembled a single "card" from database information.
What questions i really need to answer:
Flash asynchronously loads content so i'm not sure how to approach making multiple data requests for (sometimes simultaneous) battle actions, card information, or card assembly (THere can potentially be a lot of cards and card building blocks so i feel it would be inefficient to load all data with a single request). I can either have the classes responsible make those calls OR create a messenger class to handle all requests/disconnects/reconnects/messages for the entire game.
For the global messenger class approach, I am not sure how to retrieve the fully loaded data from the messenger by upstream code (as3 continues execution even if data isnt there) or how to ensure that the request pertains to the appropriate call
i could use a ID request system to uniquely identify the socket request
i could develop a custom event driven system
I could spawn multiple messenger objects in each class that i need one. <- im leaning towards this option.
On a similar note, perhaps i should handle database requests within card objects or preload all data prior to game start (This would limit me to only query for opponent card and battle data on the fly). With the one call per card object approach I was unsure if #requests per card per player will overwhelm my server or not. Node.js scales very well but i dont have the networking knowledge to understand whether all these simultaneous request on a single port would be too much.
EDIT:
I'm strongly leaning towards using a singleton XMLSocket Wrapper or an extended class of some sort to deal with all networking transactions since that seems intuitive to me. I would highly appreciate your feedback on the best approach to notify my code that the messenger received and parsed the message it asked for (since flash will proceed with execution even if data isnt there i need a good way to do this.). I read that using custom events isnt all that terrific and there are better ways... but this is how i'd approach the problem.
For example i can do (pseudocode).
m:Messenger = new Messenger(); //this is my wrapper
m.addEventListener(new CustomEvent(CustomEvent.EVENTSTRING, parseData));
m.sendData(DataObject); //calls
function parseData(e:CustomEvent) {
xml(e.data);
}
import flash.net.XMLSocket;
import globals.*;
public class Messenger
{
public static var _Socket:XMLSocket;
public var xml:XML;
public function Messenger()
{
_Socket = new XMLSocket(vars._Server, vars._Port);
_Socket.addEventListener(Event.CONNECT, onConnect);
_Socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
}
private function onConnect(evt:Event):void {
trace("Connected");
_Socket.removeEventListener(Event.CONNECT, onConnect);
_Socket.removeEventListener(IOErrorEvent.IO_ERROR, onError);
_Socket.addEventListener(DataEvent.DATA, onDataReceived);
_Socket.addEventListener(Event.CLOSE, onSocketClose);
}
private function onDataReceived(evt:DataEvent):void {
//trigger correct event here based on data identifier w/ dispatchEvent(EVENTSTRING);
}
}
About card assembly - you should store data in database that does not require recalculation, so if a card is built out of several "building blocks", you could, for example, store a sequence of blocks in a single line of database, so that when a card info for the opponent is retrieved, you just select from player_cards where player_id=... and deck_id=... and then assemble the gathered data on AS3 side. You should definitely not put this load on server.
About asynchronous loading - make sure your PVP handshake waits for both sides to successfully process cards for both own side and enemy side. You can load data asynchronously, but you'd better do a full preload while displaying a "Loading bla-bla" screen to the player, then operate with received data. Yes, you can do multiple requests to your server, and yes, you can wait for all of them to success prior to displaying a "Battle start" screen, in the meantime AS3 will wait for the loading to complete. But, about single vs multiple request - I say go with as few as possible, because every added request at the init stage is a potential to add a thousand or so requests to a single server, and a potential to put just too much strain on your server side, resulting in a self-initiated DDoS. Make sure your database structure allows streamlining of data reading operation right into the client side, so that your server is not under a heavy load from preparing the data. But also make sure to double check whatever clients report to the server, as the primary rule of client-server games is "client always lies" assumption.
Since you are planning to make server process player actions mid-battle, you can create either temporary tables on the server (SQL-based) or state objects (process-based) that will contain current game state with links to whatever abilities the cards have and their state (in hand, discarded, in play, destroyed, etc), so that when an action from the player comes, saying "this card changes state from A to B" you can easily verify if that card is in A state, then switch it into B state, performing any actions that result from this state change on both server and client sides. Make sure to clean up this set of data once the battle is over. This requires thorough planning of your server side, so that your game engine will not stall the server while running some action sequence due to excess SQL requests, for example.
About messengers - probably you should use a session approach, together with login/password authentication this way you will have sessions available as keys to determine which battle does this data packet belongs. I think also make AS3 side periodically send pull requests to the server, which should be quickly parsed by the server and the submitted enemy/server actions returned as quickly as possible, this will also ensure that disconnects will be handled and reconnects allowed.
Overall, the question is very broad, and only tips can be given, not even examples.
I am developing an online game where characters can perform complex actions against other objects and characters. I am building a REST API, and having a lot of trouble trying to follow even some of the most basic standards. I know that REST isn't always the answer, but for a variety of reasons it makes sense for me to use REST since the rest of the API uses it appropriately.
Here are some tricky examples:
GET /characters/bob/items
This returns an array of items that Bob is carrying.
I need to perform a variety of 'operations' against these items, and im having a very difficult time modeling this as 'resources'.
Here are some potential operations, depending on the nature of the item:
throw, eat, drop, hold
This is complicated because these 'operations' are only suitable for certain items. For example, you can't eat a sword. Moreover, 'eat' essentially has a side-effect of 'deleting' the resource. Using 'throw' may also 'delete' the resource. Using 'drop' may 'transform' the resource into another resource type. 'Throw' requires that I provide a 'location'. 'Hold' requires that I supply which hand to hold the item in. So how do you model these operations as resources? None of them are 'alike' because they each require different parameters and result in completely different behaviors.
Currently, I have an 'actions' resource that I POST these arbitrary actions to. But this feels way too RPC and non-standardized/discoverable:
POST /actions/throw
{
characterId: 5,
itemId: 10,
x: 100,
y: 150
}
I try to stick to resources and GET/POST/PUT/PATCH/DELETE where possible, but the base verbs tend to map directly to CRUD calls. Other, more complex operations generally can't be mapped without additional information.
Focusing on the resources, I'd probably do something like this (posting messages to the resources):
POST /characters/bob/items/{bombId}?action=throw
POST /characters/bob/items/{foodId}?action=eat
POST /characters/bob/items/{potionId}?action=add&addedItem={ingredientId}
Return an error when the action is not appropriate for the item.
Where I want a resource to “do a complex action” while remaining RESTful, I'd POST a complex document to the resource that describes what I want to happen. (The complex document could be in XML, JSON, or any number of other formats.) This is somewhat distinct from the more common pattern of mapping POST to “create a child resource”, but the meaning of POST is “do non-idempotent action defined by body content”. That's a reasonable fit for what you're after.
As part of the HATEOAS principle of discovery, when you GET the resource which you will later POST to, part of the document returned should say what these complex action documents are and where they should be sent to. Logically, think of filling in a form and submitting it (even if the “form” is actually slots in a JSON document or something like that).
This is more of a theoretical question rather than language specific, but I'm mostly referring to AS3.
Let's say I have an app that shows buttons through a couple of levels of navigation.
For example artistsAlphabetical->albums->songs or songsAlphabetical->song or albumsAlphabetical->album->song
so we'd set up a model(Data) with all the songs (the lowest common denominator - it would have the artist/album/year etc. info within the song object)
Let's say we don't have a dataset for the albums and need to extract that from songs. or we do have a datasaet and need to match them up.
Where should that fall under? Model or Controller?
I can find reasons for either, but am wondering what the "correcter" way would be.
Next we have the View with all the buttons to do the sorting.
When you click on the sort button Artists-A - that's the View sending a message to the Controller to do something (get alphabetical list of artists that start with A). The end result should be a new (paginated view if necessary) with buttons for each artist.
Which part of MVC should be responsible for each step?
Generating a list of artists that start with A
would it be the controller that says - 'Hey model - Artists that start with 'A' NOW!'
or, would it be more like 'Model - send me a list of all the Artists, I need to find the A-dawgs'?
essentially should the model do the sorting (and cache it if possible/needed) or should the logic be under the Controller, and the Model can store the cache?
So once we have a list of the artists, we need to create a button for all the ones that fit on the screen plus some previous/next buttons. Who should be creating the Buttons?
Should there be a View Controller? A Sub-Controller that only deals with the logic needed to create the views? Or would the logic be part of the View? It seems to me that the app's Controller would be all like 'not in my job description... I gave you the list you needed rest is up to you'
I feel like I'm conflicted between two views of MVC, one (mvC) - where the Controller is working like a motherlicker, and the Model is a glorified data holder and the view manages DisplayObjects. Or (an MVc) where the controller is the manager/delegator that makes sure that the Model and the View communicate properly, so that the model and view would have a fair amount of logic, and the controller would handle communication and delegate top level interaction.
While I am doing most of my stuff in AS3, I am curious how other languages would handle this. For example, in PHP Frameworks, you wouldn't need to worry about the button logic and event handling as much as with as3, where you need to watch Garbage collection, so the workload of one component there might be different than in a Cinder++, processing or actionscript app.
I don't know AS3. I do both Spring MVC/Java, which really lets you do either approach, and also Ruby on Rails, which favors smart models and dumb controllers. I like the smart model/dumb controller approach better.
So to me, anything to do with sorting and filtering the data should absolutely be done in the model, as should the process of extracting Albums from a list of Songs.
In Rails, I would put the process of creating the set of buttons in the view layer without question. If there's actual logic involved, that would go into a view helper method.
As you stated already, this comes down mostly to preference, but typically I would opt for the sorting to be done in the controller. I tend to keep my models purely about data storage and reduce the amount of functionality in them. So in your example, the model's job would be to hold all of the artists' data, and the controller's job would be to extract the artists starting with "A" from that data, and subsequently passing that sorted data to the view.
I don't use traditional MVC anymore, so I tend to think more in terms of PureMVC (proxies, mediators, and commands) now.
In general, I tend towards more functional proxies (think model) where the data gets abstracted (for the typical reasons for abstracting data). So, in your cases, there would be a MusicLibrary proxy, and would probably have methods like byArtist(), byTitle(), byRandom(), etc.
In a PureMVC app, a sequence for your scenario would look like:
Component catches mouse click and sends Mouse.CLICK
Mediator wrangling the component catches event, and sends notification SORTBY_ARTIST_CLICKED
Command which is requesting notification of SORTBY_ARTIST_CLICKED, calls the the byArtist() method on the proxy, builds a notification NEW_MUSIC_LIST w/ the data and sends it
Mediator requesting notification of NEW_MUSIC_LIST then does its thing and updates the components is is wrangling
I think this would align with what JacobM describes as smart model / dumb controller. I think that this approach leads better resuse, and also better isolates impact from chages.
I will say that in general, if I have different views of the same data (like in your case), I will use commands to push out the data, but if a view just gets a data update I will often have the view just pull the data from a proxy.