Mock Components – from Developing a React Edge

rocketborder3rev

One powerful feature in React that you learned about earlier is composing components of other components. Having one component render another one is great for modularity and code reuse, but it takes a special consideration with regard to your tests. Let’s imagine you have two components: UserBadge and UserImage, where UserBadge renders the user’s name and their UserImage. When writing tests for the UserBadge component, it is important only UserBadge functionality is being tested and that you are not implicitly testing UserImage functionality. While a co-worker might argue that testing both “is better because it’s more like real life,” you will quickly find that your tests will get harder and harder to write and maintain because they will lose focus of the “unit” you are trying to test.


LISTEN TO YOUR TESTS!

If you are concerned about your tests becoming too complex and unfocused (which you should be), then you can keep an eye out for some symptoms of this happening.


One “code smell” to watch out for is a test that requires a complex or repetitive setup process. The more painful it is to setup a test, the stronger the “smell” that there might be something suboptimal about your architecture. Often your tests are trying to give you some advice.

Here’s our plan of attack for the UserBadge test. Before rendering the UserBadge component, we should modify it so that UserImage component has been replaced by a mock component that has no real behavior. This is very dependent on the tools and architecture you have chosen for your application. For the Survey Application, we have chosen Browserify, so let’s look at that approach first. Let’s start with the basic boilerplate for a UserBadge test and a simple render call:

/** @jsx React.DOM */
var React = require("react/addons");
var TestUtils = React.addons.TestUtils;

var UserBadge = require('../../../client/testing_examples/user_badge');

describe("UserBadge", function(){
      // NOTE: This will render the actual UserImage component, 
      // which is not the desired affect
      it("should use the mock component and not the real component", function(){
        var userBadge = TestUtils.renderIntoDocument(<UserBadge />);
      });
});

You can read the full source code of our example application, a survey builder, at https://github.com/backstopmedia/bleeding-edge-sample-app.

To help us stub out the UserImage component for this test, we will use an open source module called rewireify. This module is like magic, since it allows us to rewrite local variables and local functions for a module. If you look at the source for the UserBadge module, you will see the following lines:

var UserImage = require("./user_image");
...
  render: function(){
    return (
      <div>
        <h1>{this.props.friendlyName}</h1>
        <UserImage slug={this.props.userSlug} />
      </div>
      );
  }
...

So this means that the UserBadge module has a local variable called UserImage, which is set to a react component. In the UserBadge spec, we will tell rewireify to set the UserImage local variable with a mock component. The basic approach looks like this:

var mockUserImageComponent = React.createClass({
        render: function(){
          return (<div className="fake">Fake User Image!!</div>);
        }
      });

UserBadge.__set__("UserImage", mockUserImageComponent);

Now when the UserBadge components tries to render, it will render our mockUserImageComponent and not the real UserImage component. While the above example is nice, it doesn’t account for one important side effect – test pollution. If we “__set__” a variable in one test, we need to make sure our change is reversed before the next test begins. To make sure one test doesn’t pollute another, our test should look like this:

describe("UserBadge", function(){
  describe("rewireify", function(){
    var mockUserImageComponent;

    beforeEach(function(){
      mockUserImageComponent = React.createClass({
        render: function(){
          return (<div className="fake">Fake User Image!!</div>);
        }
      });
    });

    describe("using just rewireify", function(){
      var realUserImageComponent;

      beforeEach(function(){
        // save off the real definition, so we can put it back 
        // when the test is complete
        realUserImageComponent = UserBadge.__get__("UserImage");
        UserBadge.__set__("UserImage", mockUserImageComponent);
      });

      afterEach(function(){
        UserBadge.__set__("UserImage", realUserImageComponent);
      });

      it("should use the mock component and not the real component", function(){
        var userBadge = TestUtils.renderIntoDocument(<UserBadge />);

        expect(TestUtils.findRenderedDOMComponentWithClass(userBadge, 
"fake").getDOMNode().innerHTML).toBe("Fake User Image!!");
      });
    });

  });
});

TESTUTILS.FINDRENDEREDDOMCOMPONENTWITHCLASS

We are using a utility called TestUtils.findRenderedDOMComponentWithClass in this test. We will cover the behavior of this utility later in this chapter, but for right now all you need to know is that it finds a component with the class fake.


Here is the general algorithm of the test code shown above:

  1. Define the mockUserImageComponent React component
  2. Get the value for the UserImage variable in the UserBadge module and save it in a local variable called realUserImageComponent
  3. Set the value for the UserImage variable in the UserBadge module to the mockUserImageComponent
  4. Perform the test
  5. Set the value for the UserImage variable in the UserBadge module back to the realUserImageComponent.

The good news is that this approach works great, but the bad news is that it is a lot of boilerplate code that we will probably need in almost every spec because most specs will render other components. So, this is where a custom Jasmine helper can make a large difference. What we’re going to do is write a module that has responsibilities: a function that we can call from our spec to rewire a variable, and an afterEach hook that reverses all of those changes at the end. To reverse the changes, we just keep track of all the rewire’s that we’ve done in an array and then loop through that array in the clean up phase. Here is the code for our helper module, which you write in a file called test/client/helpers/rewire-jasmine.js:

var rewires = [];
var rewireJasmine = {
  rewire: function(mod, variableName, newVariableValue){
    // save off the real value, so we can revert back to it later
    var originalVariableValue = mod.__get__(variableName);

    // keep track of everything which was rewire'd through this 
    // helper module
    rewires.push({
      mod: mod,
      variableName: variableName,
      originalVariableValue: originalVariableValue,
      newVariableValue: newVariableValue
    });

    // rewire the variable to the new value
    mod.__set__(variableName, newVariableValue);
  },

  unwireAll: function(){
    for (var i = 0; i < rewires.length; i++) {
      var mod = rewires[i].mod,
        variableName = rewires[i].variableName,
        originalVariableValue = rewires[i].originalVariableValue;

      // rewire the variable name back to the original value
      mod.__set__(variableName, originalVariableValue);
    }
  }
};

afterEach(function(){
  // unwire all modules we rewire'd
  rewireJasmine.unwireAll();

  // reset the array back to an empty state in preperation for 
  // the next spec
  rewires = [];
});

module.exports = rewireJasmine;

With this helper module in our toolbox, we can simplify our UserBadge/UserImage example to this:

var rewireJasmine = require("../helpers/rewire-jasmine");
var UserBadge = require('../../../client/testing_examples/user_badge');

describe("UserBadge", function(){
    describe("with a custom rewireify helper", function(){
      beforeEach(function(){
        rewireJasmine.rewire(UserBadge, "UserImage", mockUserImageComponent);
      });

      it("should use the mock component and not the real component", function(){
        var userBadge = TestUtils.renderIntoDocument(<UserBadge />);

        expect(TestUtils.findRenderedDOMComponentWithClass(userBadge, 
"fake").getDOMNode().innerHTML).toBe("Fake User Image!!");
      });
    });
  });
});

Look how easy that is! rewireJasmine.rewire(UserBadge, “UserImage”, mockUserImageComponent); handles the saving off of the original value and the module registers the afterEach cleanup hook.


OTHER NPM IMPLEMENTATIONS

If you are using Webpack instead of Browserify for client side code, you will want to swap out rewireify with rewire-webpack. If you are testing a Node.js application instead of client side code, you will want to use the original project rewire (the project that spawned rewireify and rewire-webpack. The interface is slightly different, but you can read more about it here.


But what if a project isn’t built with the npm/require goodies and we’re using <script> tags that store the components in a global variable? Don’t worry, you aren’t out of luck either. The pattern is exactly the same, but the code looks a bit different:

  describe("global variables", function(){
    var mockUserImageComponent, realUserImageComponent;

    beforeEach(function(){
      mockUserImageComponent = React.createClass({
        render: function(){
          return (<div className="fake">Fake Vanilla User 
 Image!!</div>);
        }
      });

      // we need to save off the real definition, so we can put it back when the test is complete
      realUserImageComponent = window.vanillaScriptApp.UserImage;
      window.vanillaScriptApp.UserImage = mockUserImageComponent;
    });

    afterEach(function(){
      window.vanillaScriptApp.UserImage = realUserImageComponent;
    });

    it("should use the mock component and not the real component", function(){
      var UserBadge = window.vanillaScriptApp.UserBadge;
      var userBadge = TestUtils.renderIntoDocument(<UserBadge />);

      expect(TestUtils.findRenderedDOMComponentWithClass(userBadge,
 "fake").getDOMNode().innerHTML).toBe("Fake Vanilla User Image!!");
    });
  });

Let’s review what we’ve learned so far:

  • How to render a component into the document
  • How to stub out a nested component with a mock implementation

flameborder_reactedge

Why use gulp?

rocketborder3rev

gulp is a build system as compared to a task runner, such as Grunt, although for all intents and purposes both tools can be used to accomplish the same result. gulp differentiates itself by focusing on optimized file operations with a limited Application Programming Interface (API) and strict set of plugin authoring guidelines.

gulp performs file operations where Grunt tasks may refer to any type of operation, including running shell commands. Although gulp does use the term task, it refers to a grouping of plugins to execute. In addition, gulp favors code over configuration as builds are configured using code, providing access to common coding techniques and libraries.

Common file operations are copying, moving, renaming, compiling, transpiling, concatenating, and minifying. These are all canonical gulp use cases.

A typical non-file related task, on the other hand, may be to commit source code to a source code repository. A gulp plugin written to do this would need to use the gulpfriendly keyword as it does not pass gulp’s plugin guidelines. Nevertheless this activity may be desired as part of the developer’s workflow and can be integrated into the build system.

Grunt was developed to handle all types of tasks, and it’s API suffers bloat as a consequence. In comparison, gulp chose to focus on a few key areas and limit the API, making it easy to grasp for newcomers.

Build Tool Comparison

PastedGraphic-1

Easy to learn

With just four methods, gulp’s minimal API provides for quick adoption and configuration. Plugin authors are also encouraged to adopt a minimal API with gulp’s development guidelines. Let’s take a look at the four methods along with their options.

gulp.task

gulp.task defines a task using Orchestrator. A task contains the operations you want to execute, where the operations are commonly provided by plugins.

gulp.task(name[, dependencies], function () {
  // perform operations
});
name
The name of the task. The task name will be accessible via the CLI, so make it something meaningful. For example, scripts or optimize or minify.
dependencies
An optional array of tasks to be completed prior to your task. Orchestrator ensures that dependent tasks are executed before this task. The dependencies are also executed in parallel to ensure maximum efficiency. This is another key differentiator over Grunt.
function
The function that performs the task’s operations. The function typically follows the pattern of collecting files from the file system, performing some operations provided by plugins, and writing the result back to the file system. We’ll take a closer look at this later.

The following example defines a task named template with a dependency on the minify task. The minify task will be executed and completed prior to the template task.

gulp.task('template', ['minify'], function () {
  // perform operations
});

gulp.src

gulp.src will often be the first operation to perform within the task function as it collects the files from the file system on which your task will operate. It takes a file matching pattern (glob), representing the file structure to read, and returns a readable stream.

gulp.src(glob[, options]);
glob
The node-glob file pattern to read. The glob simply refers to pattern matching based on wildcard characters.
options
An optional parameter to further define file criteria, such as the Current Working Directory (cwd) or whether your task needs the contents of the file read from the file system. Occasionally you may just need the file path and not the contents.

The following example collects all files with the coffee file extension located in the scripts directory or any of its subdirectories.

gulp.src('**/*.coffee', {cwd: 'scripts'});

gulp.dest

gulp.dest writes files to the specified path and is commonly the last step in the task function.

gulp.dest(path);
path
The output directory path.

The following example writes the output files to the dist directory.

gulp.dest('dist');

gulp.watch

gulp.watch performs one or more tasks when specified files change. To avoid manually rerunning the build tasks after the developer makes changes, the watch method can be configured to do this automatically by executing certain tasks when particular files are changed. The watch method plays a large part in overall developer productivity.

gulp.watch(glob[, options], tasks);
glob
The node-glob file pattern that indicates the files to monitor for changes.
options
An optional parameter to further define file criteria, such as the Current Working Directory (cwd).
tasks
An array of tasks to be executed when a file changes.

The following example runs the coffee task when any file with the coffee file extension located within the scripts directory or any of its subdirectories changes.

gulp.watch('**/*.coffee', {cwd: 'scripts'}, ['coffee']);

That’s it to the gulp API, just four methods. Define the task, get files on which to operate, write files back to the file system, and watch for file changes on which to perform more operations. Now that we know the API, let’s dig in a bit deeper and show how to use it.

Easy to use

Node.js has quickly become a widely used server-side runtime environment. Node.js runs on Windows, Linux, and Mac, and since Node.js applications are written in JavaScript, front-end developers are often up and running with relative ease.
New patterns and techniques have emerged with Node.js, such as CommonJS, to help alleviate the complexities of managing application dependencies. For example, the following code gets a handle to the coffee-script dependency using the CommonJS require syntax and executes the compile function on a snippet of code.

var coffeeScript = require('coffee-script');
var code = 'console.log "I am CoffeeScript code"';
var javaScript = coffeeScript.compile(code);

All that’s necessary is to use the require method to grab the dependency’s exposed functionality. Gulp saw no need in reinventing the wheel, but instead wanted to leverage the coding techniques of Node.js development and keep it simple. Grunt, on the other hand, introduced their own form of configuring tasks.

To demonstrate, the following build configurations will compile CoffeeScript files to JavaScript and minify the result. Let’s first take a look at the Grunt implementation.

Grunt example

module.exports = function (grunt) {
  grunt.initConfig({

    coffee: {
      compile: {
        files: [{
          cwd: 'src',
          src: '**/*.coffee',
          dest: 'temp',
          expand: true,
          ext: '.js'
        }]
      }
    },

    uglify: {
      minify: {
        files: [{
          cwd: 'temp',
          src: '**/*.js',
          dest: 'dist',
          expand: true
        }]
      }
    },
  });

  grunt.registerTask('default', [
    'coffee',
    'uglify'
  ]);

  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-contrib-uglify');
};

The coffee and uglify object properties passed into the grunt.initConfig method provide Grunt the details of how to execute these plugins. Notice the use of grunt.loadNpmTasks. This is the Grunt style of pulling in dependency functionality in lieu of CommonJS’s widely used require.

Also there is no readily-available ability to perform operations outside of a Grunt plugin or task. For instance, the developer may need to execute some functionality on the compiled CoffeeScript but before the uglify step kicks in.

Can you identify all of the tasks in the Grunt configuration? You can see the registerTask method and can assume default is one of them. But did you see the other two? Both coffee and uglify are tasks as well. With gulp, on the other hand, a task is a task.

Now let’s configure gulp to do the same thing as above.

gulp example

var gulp = require('gulp');
var coffee = require('gulp-coffee');
var uglify = require('gulp-uglify');

gulp.task('default', function () {
  return gulp.src('**/*.coffee', {cwd: 'src'})
    .pipe(coffee())
    .pipe(uglify())
    .pipe(gulp.dest('dist'));
});

The gulp configuration looks like any other Node.js file. In fact, gulp itself is included as a dependency using the CommonJS require method, as are CoffeeScript and Uglify. And since gulp configuration is code instead of a configuration object, like Grunt, all common development privileges are allowed.

Notice the dramatically reduced gulp configuration when compared to Grunt. The code tells the story.

  1. Get a handle to gulp
  2. Get a handle to CoffeeScript
  3. Get a handle to Uglify
  4. Define the task (default in this example)
  5. Collect all CoffeeScript files from the src directory or any of its subdirectories
  6. Execute coffee to compile CoffeeScript to JavaScript
  7. Execute uglify to minify the JavaScript
  8. Write the files to the dist directory

The story is not as evident when reading the Grunt configuration, however.

These two examples show a basic configuration using Grunt and gulp. Digging further we can see the differences aren’t only superficial. These builds can be expected to execute repeatedly and continuously, and gulp set out to make them fast.

flameborder_learningswift

Creating Levels in Pencil Adventure with Swift: An Excerpt from Learning Swift

rocketborder3rev

There are many ways to create a level for your game. For example, you can make a custom level editor and store only the node type and position in each level. You can also consider using a third party level editor, such as the Tiled Map Editor, which is a great tool for tile mapping. The best part is that it is free! So check it out if you want to build a tile map game.

You can read the full source code of our Pencil Adventure game here on Github.

In our Pencil Adventure project, we use the hybrid way to create levels. Each level was designed in Xcode’s level editor with texture names and position definition in the game. The physics definition for each item was added to the sprite node when the game scene’s loaded.

swiftfig1

In addition, we defined the background items in the level editor for a parallax effect. We hope you’ve been following along with the code in the previous chapters. In this chapter, you will start with creating a new level for the game to make it fun. Now, let’s get started by using the level editor in Xcode.

Level editor

In our game, we used Xcode’s level editor to create each level. It’s easy to update the position of the objects and give you direct visual feedback in the level design. It is versatile enough to allow specifying a physical definition, such as collision category, physics body, and so on. The level will be saved as a binary file with a sks name extension. Let’s walk through the following few steps to create a level.

  • Create Sprite Kit scene file
  • Add SKSpriteNode to scene
  • Edit sprite property
  • Add More sprites to scene
  • Edit physics property through level editor
  • Edit physics property through game scene

Go ahead and open Xcode to continue with the Pencil Adventure project. First, create a new level in the project. Go to Xcode and create a file. When the file type dialog window shows up, select the Resources group under iOS from the left panel, then select SpriteKit Scene, and click Next.

swiftfig2

Save the scene file as 1.sks in the project. Note, sks is the file name extension for SpriteKit Scene file.

swiftfig3

Ok, you now have a blank scene in front of you to create a new level. Notice on Xcode’s right side, there is the SKNode inspector panel on the top right corner. That’s where you can edit the details about each Node’s property. For example, the texture, size, position:

swiftfig4

Go to the object library located at the bottom right and drag a SKSpriteNode to the scene in the center.

swiftfig5

Cool, you just added a shelf to the scene by simply dragging a SKSpriteNode to the scene. Update the texture name with the shelf image. You will notice the size will be automatically updated to the texture size. You can drag the object when it’s selected to change the position in the level.

swiftfig6

Now you can try to add a Sharpener and a box in the scene. Move these objects around to give Steve some space to jump forward. You can actually copy the selected sprite node and paste it in the scene. That may help when you plan to create a longer level.

swiftfig7

Now go ahead and design a level you like with the assets in the game. When you are done with this first level, run the game and play it!

Hmm, well, Steve runs but the game does not have a solid feedback when Steve runs into the power-up: the sharpener. Remember you defined the category for shelf and sharpener in the game scene? You need to define the physics body on each object individually. You can actually edit the physics body property in the level editor directly. Let’s take a look at how to edit the physics definitions next.

swiftfig8

As shown in the image above, in the physics definition section, you can choose the bounding rectangle as body type, and deselect the dynamic option to make the object static. Next, you can update the collision mask and category mask to allow Steve to have correct collisions with the shelf. Select a shelf in the scene and update the Category Mask to 2, the Collision Mask to 1 and leave the Field Mask to 0.(We don’t use Field Mask in the game.)

These steps seems fine if you plan to create a short level, but in Pencil Adventure it seems difficult to keep track of the physics definition inside the level editor for every object. Ideally, we would like to have a subclass of SKSpriteNode for power-up, so we can custom the physics defination inside the class. However, at the time of writing, Xcode’s level editor doesn’t support adding subclass SKSpriteNode yet. Let’s hope this feature will be available in the future release.

In our Pencil Adventure game, we actually use the level as the visual level design tool to layout the position for each sprite node in the game scene. Each object’s physics definition is added by code when the scene’s loaded in the game. In the next section, let’s add this code change to the GameScene.swift file.

Physics definition

You designed a level and added a shelf, sharpener and box in the level editor with the custom position, name and texture. Next, you can set the correct physics definition to each object when the level is loaded in the game scene. In this dynamic loading process, you will define sprite’s physics body based on the name defined in the level editor.

Go ahead and add the following code changes to the GameScene.swift file.

private func ensurePhysicsBody(sprite: SKSpriteNode, 
useTextureAlpha: Bool = true) -> Bool { //#1
     // Make sure our sprite has a physicsBody
     if sprite.physicsBody == .None {    //#2
           // First, try to create a physicsBody from the 
texture alpha
           if useTextureAlpha && sprite.texture != .None {
                sprite.physicsBody = SKPhysicsBody(texture: 
sprite.texture, alphaThreshold: 0.9, size: sprite.size)
                }
                // Next, try to create a physicsBody 
from the sprite's smallest
                // bounding rectangle
                if sprite.physicsBody == .None {
                      NSLog("*** Falling back to rectangle 
for sprite: \(sprite.name)")
                      sprite.physicsBody = SKPhysicsBody
(rectangleOfSize: sprite.frame.size)
                }
			
                // If we still don't have a physicsBody, 
just move on to the next one
                if sprite.physicsBody == nil {
                      NSLog("*** Falling back to no 
physicsBody for sprite: \(sprite.name)")
                      return false
                 }
                 // Default these to no collisions/contacts
                 sprite.physicsBody?.categoryBitMask = 0
                 sprite.physicsBody?.collisionBitMask = 0
                 sprite.physicsBody?.contactTestBitMask = 0
            }
            // Defaults for the physics body
            sprite.physicsBody?.dynamic = false
            return true
      }

First let’s take a look at #1 the definition of this function.

ensurePhysicsBody(sprite: SKSpriteNode, useTextureAlpha: Bool = true) -> Bool

This function takes two parameters: sprite and useTextureAlpha. -> Bool indicates there is a return value for this function and it’s a Bool value.

#2 has a new value in Swift: .None

That’s because physicsBody is an optional property in the sprite node class. When the optional value is not defined, in this example, it means that the object does not have a physics body defined.

sprite.physicsBody == .None

We are using this condition to make sure this code won’t impact any existing physicsBody definition in the sprite node.

In the above code listing, you created a function to define the physicsBody property for a given sprite node, and the return value is Bool. If the physics body is not defined, you will create the physics body from the bounding rectangle of the sprite node. By default, the object will be static and won’t move.

Ok, now with function ensurePhysicsBody(sprite: SKSpriteNode, useTextureAlpha: Bool = true) -> Bool defined, you can call it inside the sprites enumeration. The setupAccessories() function in the following code listing:

private func setupAccessories() {
   for child in self.children as [SKNode] { 	  //#1
      if var sprite = child as? SKSpriteNode {    //#2
         if sprite.name == .None {
            continue
         }
         sprite.zPosition = levelItemZPosition   //#3 
         if let spriteSpec = sprite.name {       //#3 
            var components = spriteSpec
.componentsSeparatedByCharactersInSet(NSCharacterSet
(charactersInString: "|"))
            if (components.count <= 1) {     //#4 
            if ensurePhysicsBody(sprite) {
              sprite.physicsBody?.categoryBitMask 
|= levelItemCategory
              sprite.physicsBody?.collisionBitMask 
|= heroCategory
            }
              continue
         }
         sprite.name = components[0]        //#5 
         components.removeAtIndex(0)        //#5 
         for accessory in components {		//#6 
           switch accessory      {  //#7
           case "background":       //#8
	     sprite.zPosition = BackgroundZPosition
	
	    case "finish":           //#9
	     if ensurePhysicsBody(sprite, 
useTextureAlpha: false) {
	     sprite.physicsBody?.categoryBitMask 
|= finishCategory
	     sprite.physicsBody?.collisionBitMask 
|= heroCategory
		       }
	    sprite.alpha = 0
							
            case "powerup":         //#10
             if ensurePhysicsBody(sprite) {
             sprite.physicsBody?.categoryBitMask 
|= powerupCategory
             sprite.physicsBody?.contactTestBitMask 
|= heroCategory
		 }

        case "death":           //#11
          if ensurePhysicsBody(sprite) {
	     sprite.physicsBody?.categoryBitMask 
|= deathtrapCategory
	     sprite.physicsBody?.collisionBitMask 
|= heroCategory
		}
							
        default:                //#12
	   if ensurePhysicsBody(sprite) {
	     sprite.physicsBody?.categoryBitMask 
|= levelItemCategory
	     sprite.physicsBody?.collisionBitMask 
|= heroCategory
            }
          }
        }
      }
    }
  }
}

As mentioned in the last section, the Xcode level editor doesn't allow for any custom data to be added to a node or the subclass SKSpriteNode. So we've used the name field to add additional information in the form of a sprite specification. We format the name with a special character | to separate node name and the type: (sprite node name)|(accessory type). Therefore, a sprite named picture|background would represent a sprite named picture that is a background accessory type. We then remove the accessory type from the name and setup that accessory type appropriately.

You started for-loop in #1 to go through every node in the scene and defined #2 if condition to make sure the current child is a spirte node.

In #3 you set the sprite's zPosition and check the sprite name for additional information if the accessory type is defined with |(accessory type).

Move on to #4, if there's no accessory defined in the sprite specification, you can assume that's just a normal level item. Next you add the physics body definition to the sprite by calling the function defined earlier and continue with the loop.

Next in #5, you replaced the sprite's name with the accessory type in the sprite specification so you can apply the appropriate properties to this sprite in #6 in the for-in loop.

Ok now let's spend a bit time looking at the switch case loop in #7. You've defined categoryBitMask and collisionBitMask in Chapter 5 for the game scene:

let heroCategory: UInt32 = 1 << 0
let groundCategory: UInt32 = 1 << 1
let levelCategory: UInt32 = 1 << 2
let powerupCategory: UInt32 = 1 << 3
let deathtrapCategory: UInt32 = 1 << 4
let finishCategory: UInt32 = 1 << 5

You may notice deathtrapCategory is new here. We added this object to the game as TNT boxes in the indoor world and propane tanks in the outdoor world. When Mr Steve runs into the deathtrap objects, the game is over.

Now you can assign the correct categoryBitMask and collisionBitMask when a matching sprite type's found. For example, #8 handles the background objects. All of the objects in the background will be further away and they have no physics body in the game scene, so you simply assign the sprite's zPosition as BackgroundZPosition. The BackgroundZPosition is defined as a constant in the game scene:

let BackgroundZPosition: CGFloat = -10

This will add more depth to the game visual effect. In the next section, we will spend more time covering scrolling with parallax effect.

#9 handles the finish line. In the level editor, the finish line's created with a name box|finish. The finish line is a tall skinny rectangle box with categoryBitMask equals to finishCategory, and collisionBitMask equals to heroCategory. We want to hide this object so the alpha's 0.

#10 handles the power up. Similar to the finish line, power up is added with a name sharpener|powerup in the level editor, so we want to assign the correct categoryBitMask and collisionBitMask to the sprite.

#11 handles the death trap, the sprite node name is "box|death" in the level editor.

#12 takes care of the rest of level items, the brick wall, the stone, the shelf, the stool and etc.They all share the same categoryBitMask.

Now let's call the function setupAccessories() when the game scene's loaded.

        public override func didMoveToView(view: SKView) {
	super.didMoveToView(view)
        physicsWorld.gravity = CGVector(dx: 0.0, dy: -9.8)
        physicsWorld.contactDelegate = self
        // setup physics defination on every sprite
	setupAccessories()
		...

That's a long list of code changes. Now with the physics defined on the objects in the level, you can play the game and take a break from all the hard work you've put into this project, taking an adventure with Mr Steve.

Create more levels

Now that you have the tools to make a level, give it a try and create some interesting and challenging levels. You may also fork this project on github and share your levels with all of the readers. https://github.com/jocelynlih/SwiftGameBook

flameborder_learningswift

Controllers in Ember.js

rocketborder3rev

An excerpt from Developing an Ember.js Edge.

Controllers have two responsibilities in Ember:

  • Manage transient state for sections of the running application. This may involve setting properties on the controller, and having the controller handle some actions.
  • Decorate models for presentation.

Ember encourages the decoupling of application state (“Is the sound muted?”) from the visual representation of that state (“Is the speaker icon crossed out?”). Regardless of if the speaker icon is displayed, the app needs to keep track of the mute state.

A view’s only responsibility is to interface with the DOM. It handles events (like “click” or “drag”), and may modify the DOM directly with jQuery or other libraries. Views are normally quite temporary instances, and ill suited for keeping track of application state. They can cross out the speaker icon when the sound is muted, but once a view is no longer displayed its Ember.View instance is destroyed, losing that state.

Controllers are longer-lived objects that exist regardless of if their information is displayed. Here is an example of storing the isMuted property on a controller, and using it to control the UI:

0001:var App = Ember.Application.create();
0002:App.ApplicationController = Ember.Controller.extend({
0003:  isMuted: false
0004:});
0005:Ember.TEMPLATES['application'] = Ember.Handlebars.compile(
0006:  ''
0007:);

Building on what you should know about Handlebars, the class string will read speaker-icon muted when isMuted is true, and speaker-icon unmated when isMuted is false.

The view object (which renders the template) can be destroyed, and still the controller instance will keep track of the mute state. Another view could attach to the same controller, and show identical information elsewhere on the page and in a different manner. The controller has given us a mechanism to decouple state from how it is displayed.

Changing State with Actions

In these examples, views are generated by Ember. Since there is no need to customize it, there is no need to declare it.

With an application, we can use actions to send messages to the controller. These messages change the application state.

0001:var App = Ember.Application.create();
0002:
0003:Ember.TEMPLATES['application'] = Ember.Handlebars.compile(
0004:  ''
0008:);
0009:
0010:App.ApplicationController = Ember.Controller.extend({
0011:  isMuted: false,
0012:  actions: {
0013:    toggleMute: function(){
0014:      this.toggleProperty('mute');
0015:    }
0016:  }
0017:});

In this example the ApplicationController is presenting state to the template (as isMuted), and also reacting to messages from the UI requesting that the state be changed. The {{action “toggleMute”}} helper fires an action at the default target of the template, which is wired to be the controller. The controller can then update its state, and via Ember’s bindings the UI is updated to toggle between the “mute” or “unmuted” class.

Controllers can share their state with other controllers, and have parent-child relationships. Actions can bubble up through these relationships, making them a powerful and important part of how complex applications are structured. Near the end of this chapter this is discussed in more detail.

Opening this chapter, it was stated that controllers have two roles. Managing state, and decorating models. Before going into how controllers work in union, let’s cover how they fulfill the decorator pattern.

Decorating A Model With ObjectController

Models represent persisted data for a domain object. While an application is running, there may be properties describing a model that are specific to the application state and should not be persisted. For example:

0001:var profile = Profile.find(yehuda);
0002:
0003:profile.get('name'); // -> Anyone can see Yehuda's name
0004:profile.get('isEditable'); // -> Only Yehuda can edit his name

The name property can be persisted and displayed as it is. The isEditable property is related to the user’s session. Only Yehuda may edit his own profile. This second property is inappropriate to store on the model since it is not persisted and may have a different value in different contexts.

Here is where a decorator becomes useful. The ObjectProxy class provides a way to present the isEditable property as part of a profile without actually storing it on the profile.

0001:var Editable = Ember.ObjectProxy.extend({
0002:  isEditable: false
0003:});
0004:
0005:var profile = Profile.find(yehuda);
0006:
0007:var editableProfile = Editable.create({
0008:  content: profile
0009:});
0010:
0011:// Properties read from the proxy will fall through
0012:// to the `content` property.
0013:
0014:editableProfile.get('isEditable'); // -> is false
0015:editableProfile.get('name'); // -> Yehuda's name
0016:
0017:// Properties are set on the proxy if they are defined
0018:// on the property when it is extended or created.
0019:
0020:editableProfile.set('isEditable', true);
0021:editableProfile.get('isEditable'); // -> is true
0022:profile.get('isEditable'); // -> is undefined. 
      // isEditable is only on the proxy.
0023:
0024:// Properties are set on the content object if they
0025:// are not defined on the proxy.
0026:
0027:editableProfile.set('name', 'Yehuduh');
0028:editableProfile.get('name'); // -> is Yehuduh
0029:profile.get('name'); // -> is Yehuduh

The object proxy is at the core of Ember object controllers. To demonstrate object controllers we will use an application, and this time, a route.

0001:var App = Ember.Application.create();
0002:
0003:Ember.TEMPLATES['application'] = Ember.Handlebars.compile(
0004:  '{{name}}' +
0005:  '{{#if isEditable}}' +
0006:    'edit' +
0007:  '{{/if}}'
0008:);
0009:
0010:App.ApplicationController = Ember.ObjectController.extend({
0011:  model: {
0012:    name: 'Yehuda'
0013:  },
0014:  isEditable: false
0015:});

Note the use of model here instead of content. The two are aliased and interchangeable in object and array controllers.

The properties of name and isEditable can both be accessed by reading right off the controller. There is no need to call model.name to display Yehuda’s name. A more complicated example could not only decorate the model with a new property, but change an existing property.

0001:var App = Ember.Application.create();
0002:
0003:Ember.TEMPLATES['application'] = Ember.Handlebars.compile(
0004:  '{{model.name}} has become the {{name}}!'
0005:);
0006:
0007:App.ApplicationController = Ember.ObjectController.extend({
0008:  model: {
0009:    name: 'Yehuda'
0010:  },
0011:  name: 'Tomhuda'
0012:});

Showing, “Yehuda has become the Tomhuda!” Of course hardcoding models to controllers is less than useful in the real world, so Ember will set the model of a controller base on what is returned from the model hook of it’s route:

0001:var App = Ember.Application.create();
0002:
0003:Ember.TEMPLATES['application'] = Ember.Handlebars.compile(
0004:  '{{name}} is just plain old {{name}}!'
0005:);
0006:
0007:App.ApplicationRoute = Ember.Route.extend(function(){
0008:  model: function(){
0009:    return { name: Yehuda };
0010:  }
0011:});

When an object is returned from the model hook, Ember will generate an ObjectController for you. So {{name}} will be read through the object controller to the model. Often, you may need to show a list of models an not a specific model, and in that case Ember provides a slightly different proxy.

rocketborder.bottom

Ember Classes and Inheritance

rocketborder3rev

An excerpt from Developing an Ember.js Edge.

JavaScript is an object-oriented language, and features inheritance of properties and methods. Unlike Java, C#, Python, or Ruby, which all employ “classical” inheritance, JavaScript implements “prototypal” inheritance. The difference lies in where objects look to find property and method definitions.

When a method is called on an object with classical inheritance, that object looks to a class for the method’s definition. If the class does not provide the method, the object will look through a chain of superclasses for a fitting method. In prototypal systems, classes do not exist. Instead, an object will look for a method defined on itself, and if it cannot be found, look to its attached prototype. The prototype is just another object, which can in turn have its own prototype. Thus, a chain of object instances is traversed when looking for a method instead of classes.

In JavaScript, an object’s prototype is set as a property on it’s constructor. This constructor must be called with the new keyword to properly initialize the object:

0001:var ParentObjectConstructor = function(){};
0002:ParentObjectConstructor.prototype = {
0003:  foo: function() { return 'bar'; }
0004:};
0005:
0006:var MyObjectConstructor = function(){};
0007:MyConstructor.prototype = new ParentObjectConstructor();
0008:
0009:var myObject = new MyObjectConstructor();
0010:myObject.foo()  // => 'bar'

JavaScript’s prototypal inheritance has some limitations. There is no concept of calling “super”: MyObjectConstructor cannot have its own definition of foo that delegates to the parent. There are no mixins, only parent objects. For each parent, an object must be instantiated.

Ember.Object provides a more classical and flexible JavaScript object:

  • Ember.Object and its descendants behave like classes.
  • The init property becomes the object constructor.
  • Subclasses can be created by calling extend on the parent class.
  • Instances can be created with new MyClass() if you wish to pass arguments to init, or with MyClass.create({ newProp: 'foo' }); if you want to add properties at initialization time.
  • Available methods can be added or overridden on an existing class (aka “monkey patching”) by calling MyClass.reopen({ addedProp: 'foo' }).
  • Class methods can be added with MyClass.reopenClass({ classMethod: function(){} });.

Let’s explore these features. First, open Chrome. Then, navigate to the starter kit and open the JavaScript console.

Create an instance of an Ember.Object:

var myInstance = new Ember.Object();

Confirm that the variable is an Ember.Object:

myInstance instanceof Ember.Object;  // => true

Set a property on an Ember object:

myInstance.set('name', 'Tom Dale');

Get a property on an Ember object:

myInstance.get('name');  // => 'Tom Dale'

You can also define properties of the object upon creation:

0001:var fido = Ember.Object.create({ animal: 'dog' });
0002:fido.get('animal');  // => 'dog'

Now, define a class that inherits from Ember.Object: When calling extend, the properties you want to present on instances of that class (instance properties and methods) are passed as an object. Let’s try it out:

0001:var Animal = Ember.Object.extend();
0002:var Dog = Animal.extend({ sound: 'woof' });
0003:
0004:var spot = new Dog();
0005:spot.get('sound');  // => 'woof'
0006:
0007:var Beagle = Dog.extend({ sound: 'howl' });
0008:var snoopy = new Beagle();
0009:snoopy.get('sound');  // => 'howl'

Reopen a class and add a property. What do you expect to happen?

Beagle.reopen({ sound: 'hoooooowl' });

Existing instances are not affected:

snoopy.get('sound');  // => 'howl'

But new instances are affected:

0001:var rover = new Beagle();
0002:rover.get('sound');  // => 'hoooooowl'

The object of properties passed to extend is really just a mixin. You can create named mixins and pass them to extend in the same manner as an object.

0001:var Adoptable = Ember.Mixin.create({
0002:  hasOwner: function() {
0003:    return !!this.get('owner');
0004:  }.property('owner')
0005:});
0006:
0007:var GoldenRetriever = Dog.extend(Adoptable, {
0008:  sound: 'ruff'
0009:});
0010:
0011:var dog = new GoldenRetriever();
0012:dog.get('hasOwner');  // => false
0013:dog.set('owner', 'Troy');
0014:dog.get('hasOwner');  // => true
0015:dog.set('sound');  // => 'ruff'

Mixins are a familiar pattern to many developers using object-oriented programming. They patch a class with methods or properties without providing a class themselves. A mixin cannot be instantiated; it can only extend a class or instance. Applied mixin methods can call methods applied before themselves with _super, and in fact the object passed to extend( is treated just like a mixin.

Ember comes packed with some powerful OO programming features. The Ruby programming language is an obvious influence, but Ember is far from a being a clone of Ruby’s functionality. In ambitious applications and large codebases, you gain a quick appreciation for how Ember fundamentals help you compose objects and interfaces.

rocketborder.bottom

The Mini Design Sprint Polishes iOS 7 App

We had the pleasure of working with Ellie Volckhausen on a mini design sprint. Under great time pressure, Ellie created the designs for our BepBop app, which has been submitted to the App Store. Check out Ellie’s rockinrollmom blog post for more details, and check back here for when the app is available.

And take a look at our Developing an iOS 7 Edge book page for more details about the book.

Bleeding Edge Press in Round 2 of Intuit’s Superbowl Competition

We are battling it out in Round 2 of the Intuit Small Business Big Game
competition, with the ultimate prize of having a commercial aired of our
business during the 2014 Superbowl.

Here is a video that we created about Bleeding Edge Press:



Please vote for us!

Thank you,

Bleeding Edge Press