Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: May 2011

Davis W. Frank

DRYing up Jasmine Specs with Shared Behavior

Davis W. Frank
Sunday, May 29, 2011

When writing nicely encapsulated code and you have a group of objects that share an interface (pick your favorite patterns), you often want to share your test code as well. If the system models financial accounts with credits and debits, and you make a change to the reconciliation code, you want to run a core set of specs against all cash, loan, and credit card account objects.

People ask how to do this in JavaScript on the Jasmine mailing list every so often.

So here’s an example of “Shared Example Groups” in Jasmine.

This Game spec looks totally fine for a basic ball game. But what if I want to have multiple different types of ball games?

Here are specs for Basketball and (American) Football:

The specs related to the Game itself are inline. That doesn’t feel very DRY and really, we want to test the interface with the same code. We’re working in JavaScript. So we write a function.

Jasmine works by building up all the functions to execute at spec run time. When you call describe, the passed-in function is executed immediately. Inside the describe, the calls to beforeEach, afterEach and it queue up the passed-in functions for execution later, when you want to run your specs.

This means you can put all of your shared specs, including any beforeEach calls, in a function that can be executed as needed. Like this:

Each time sharedBehaviorForGameOf is called, the three before and two spec functions are queued up. Call it twice and you’ll wind up with four new specs in your Jasmine environment.

And since it’s a function, yes, you can pass parameters. The context parameter can be used to pass in a ball and a game for use in the shared specs. Since the “(shared)” describe function is called each time sharedBehaviorForGameOf is called, there will be a separate closure for the local ball and game.

So now we can refactor our specs to use our function.

This is a useful technique, but use it appropriately and with a little caution. Use it in situations for consistent testing, not just to DRY up your specs for DRY-ness’s sake.

Keep the varied behavior (like the field goal scoring above) outside your shared behavior function instead of using the parameters. The parameters should be for the object(s) under test, not their behavior.

And lastly, (as always) keep your mind on your JavaScript closures.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Nicholas Greenfield

Standup 5/27/11

Nicholas Greenfield
Friday, May 27, 2011

Interesting

  • For Noobs.

form_for Non Active Record models, need to:

include ActiveModel::Conversion

extend ActiveModel::Naming

def persisted?

false

end

*New version of TeamCity which includes:

-Free for and unlimited amount of users.

-Personal Builds on branches for Git and Mercurial

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Phil Goodwin

Standup 5/27/2011 Hack For Change, Guiderails goes public, Jenkins & Jasmine jems

Phil Goodwin
Friday, May 27, 2011

Helps

*Is there a way to change the URL that CCRB pulls from when it builds?

“Use Jenkins” (we will be standardizing on Jenkins in the near future anyway)

Apparently the answer has been found successfully in the past by grepping through the Ruby portion of the CCRB source.

Interesting

  • Hack For Change, sponsored by Change.org is inviting engineers and designers to spend 24 hours to build a web or mobile app that can help advance positive change. Top-rated hacks will be awarded a total of $10,000 to ensure their continued success and will gain recognition through widespread media coverage and promotion. http://hackforchange.com

  • Guiderails: Pivotal’s Rails 3 Templates, has been made publicly available on GitHub. https://github.com/pivotal/guiderails

  • While there is not consensus on how hash tags in URLs that are being redirected should be handled, Safari stands apart from most other modern browsers by throwing them away entirely.

  • When configuring a new project for Jenkins, remember to specify the branch to build, otherwise Jenkins will try to pull and build all branches from the repo.

  • Jasmine has a bug in its “runs and waits for” construct that causes it to ignore changes to the defaults for the timer and message on the “waits for” block.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Alexander Murmann

Standup 05/26/2011

Alexander Murmann
Thursday, May 26, 2011

Helps

Disappearing SSH keys between bash sessions

Using ssh-add will make a ssh key available for a bash session. However, on our new OS X images the key will not be available in new bash sessions and has to be re-added.
It was suggested to check the ssh-config to see if something is resetting the key.

Interesting

MySQL gem on Ubuntu box

Compiling the mysql gem fails on an Ubuntu production box:

ERROR: Error installing mysql:
ERROR: Failed to build gem native extension.

If you first install libmysql-rubyand libmysqlclient-dev you will be able to install the mysql gem as usually.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mark Michael

What Powers Pivotal Tracker: Client side architecture

Mark Michael
Wednesday, May 25, 2011

So what makes Tracker work? I will be doing a series of technical blog posts to explain that, starting with a deep dive into the client side architecture. In future blog posts I will highlight Tracker’s server side architecture and hosting environment, the external services Tracker uses and what major architecture changes we’re considering.

Basic principles

The client side architecture is the heart and soul of Tracker and is largely based on two user design principles. First, users should not have to “reload” the page or perform any action to see changes made by other users. Second, users should see the affects of their changes immediately without having to wait for the server to respond.

Tracker accomplishes these design principles by using a propriety based JavaScript MVC architecture built on top of a command queue. A change made by a user results in a command being enqueued and executed on the client and then sent to server. Commands update domain models which in turn notify their dependent views, which create, update and remove the html elements you see on the page.

Client Side Architecture Diaram

Keeping the client up to date

The client is kept up to date by periodically polling for changes. Changes are returned in the form of commands which are executed on the polling client the same way they were executed on the originating client which in turn update domain models that notify the views, which create, update and remove the html elements you see on the page. This client polling approach results in about 2k server requests per second at peak, with the majority of the traffic being handled by memcached processes sitting behind our nginx servers. Other than a few glitches here and there, this polling approach has worked well for us, but with ever-increasing traffic, we are getting closer and closer to its limits and we are considering moving to WebSocket/Socket.IO based push approach. I will dive into a deeper discussion of what we’re considering in future blog posts.

Merging changes

It’s important to merge changes from other people on the client without losing what a given user is in the middle of working on. This can be tricky, but here is how it works in Tracker. First, changes from other people are merged in as soon as a client receives them, paying careful attention not override the user’s local changes. Tracker keeps track of all of the user’s local changes so it can determine which of the incoming changes can be safely merged in. Second, Tracker ensures that all commands are executed in order. If the client was up to date before the change was made, the user’s changes are saved to the database, a command representing the change is inserted into the database and a successful response is returned. If the client wasn’t up to date, the user’s changes are not saved and and a list of “stale” commands are returned to the client. The client’s command queue then rolls back the command initiated on the client, executes the stale commands from the server, re-executes the original command and sends it back to the server. Rolling back a command entails undoing any domain changes that the command execution made.

Rich domain

Another important part of Tracker’s client architecture is its rich client-side domain. The rich JavaScript domain allows the client to quickly show how a change affects everything on the page. For example, moving a story into the current iteration may push stories below it into the backlog. Iterations on the client are dynamically recalculated on the client whenever any significant domain changes are made. This rich domain on the client also allows us to provide “what if” velocity change functionality, real time validation feedback, team strength and iteration length changes and more.

JavaScript libraries

As many of you have noticed, Tracker is currently using Prototype, YUI and jQuery libraries for various utilities and event handling, but we are in the process of moving completely to jQuery. We are also looking into the feasibility of replacing our proprietary MVC architecture with Backbone.js as well as looking closely at Socket.IO and node.JS. It’s possible that the next generation of Tracker will be built using combination of Backbone.js, Socket.IO and node.JS.

The power of TDD

As you can see, Tracker’s client side architecture is fairly complex. What keeps the code manageable and allows us to keep rolling new features out, is that we test-drive all of our JavaScript code, the same way we write our Ruby on Rails code. We currently have over 1600 JsUnit tests and several dozen selenium tests just for the “stories” page.

Stay tuned for more blog posts on the technical details behind Pivotal Tracker.

P.S. If you’d like to help us take this architecture to the next level, we’re hiring!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Nicholas Greenfield

5/25/11 I have a little Chutzpah for my 2nd standup blog post

Nicholas Greenfield
Wednesday, May 25, 2011

Help

Todd P asks,

How do you properly render a string containing UTF-8 characters across all views?

Interesting

  • Todd P answers his own help question this morning:

This is with a MySQL database. When you’re displaying UTF-8 data, the error you get is:

“incompatible character encodings: ASCII-8 BIT and UTF-8″

I added the following to config/environment.rb:

Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

And switched from the mysql gem to mysql2 (0.2.7). Also, make sure to update the adapter in config/database.yml.

  • Ian passes along our buddy @flavorjones explaining how to coerce ActiveRecord to perform joins across databases

*Lisette brings us the Yiddish word of the day Chutzpah

Events

  • Hope to see everyone at this weeks happy hour.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Phil Goodwin

Standup 5/25/2011 Cloudfront logs, terrible YAML, and RubyMine can CanCan

Phil Goodwin
Wednesday, May 25, 2011

Helps

*Is there a way to log in and download log files from Cloudfront, preferably programmatically? They can be obtained from the management console but access is needed from the command line.

Interesting

  • In Ruby 1.9.2 the delayed_job facility uses the Psych parser to serialize and Syck to deserialize the delayed job, with unpleasant results. One way to solve the problem is to go into the Ruby installation and “if false” away the Psych source code, it’s an admittedly terrible approach, but it has the appeal of actually working.

  • Ruby Mine does not behave well with CanCan out of the box.
    The problems can be fixed by editing the CanCan Ruby file and commenting out the line that sets rspec equal to spec unless rspec is already defined.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Dan Podsedly

Tracker going all HTTPS

Dan Podsedly
Tuesday, May 24, 2011

About six months ago, a certain Firefox extension made headlines by making it incredibly easy for people to intercept insecure web cookies and access private information on major web sites such as Facebook, as well as Pivotal Tracker.

In response, we made session-wide HTTPS enabled by default, but made it possible to disable it on your profile. We also left the option to force HTTPS only access for specific projects.

This partial HTTPS approach required us to use a somewhat complicated secure cookie scheme to prevent secure session hijacking (aka “sidejacking“). While this did close the door to this particular attack vector, it introduced some session instability, especially in Safari, due to intermittent dropping of secure cookies. Also, full HTTPS is generally considered to be more secure.

In next week’s release, Tracker is going all HTTPS. The static front pages will remain non-HTTPS by default, but all internal pages, for example the dashboard and project pages, will now be HTTPS-only. This will make Tracker more secure, and it allows us to remove the extra cookies related to session hijacking prevention, which should help with unintentional browser session expiration.

In addition, we’re improving how the “remember me” option works – it will now allow you to stay signed in for 2 weeks in multiple browsers.

Note: You will continue to be able to use the API via plain HTTP, unless the project you’re accessing has the “Use HTTPS” option set.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Dan Podsedly

Pivotal Tracker Analytics: Measure your development process and win an iPad!

Dan Podsedly
Monday, May 23, 2011

GoodData, provider of an on-demand, cloud-based business intelligence platform, has just launched Pivotal Tracker Analytics, a brand new application to help you measure your agile development process.

Powered by the GoodData cloud BI platform, Pivotal Tracker Analytics allows you to analyze your stories, burndown of the backlog and icebox, as well as velocity. It takes weekly snapshots of your data, and allows multi-dimensional analysis across iterations, stories, and time. You can also create custom dashboards, with the metrics that matter the most to your team.

As part of an early access program for Pivotal Tracker Analytics, GoodData is looking for help from Tracker users to to design reports and dashboards that will benefit the entire community. The top three dashboard designs will win an iPad 2!

Check out the GoodData announcement blog post for all the details, and to sign up.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Nicholas Greenfield

May 23rd 2011 [Standup][NYC]

Nicholas Greenfield
Monday, May 23, 2011

Help

“When adding “use strict” into a java script function, JSlint activates strict mode for all javascript.”

How do we make “use strict” apply to just one function?

Interesting

  • Thanks to Peter for donating his collection of MAKE magazines to the Pivotal Library. If you need inspiration for your next hardware hacking project, be sure to check them out.

  • Lee has been working on an open source project called Lobot. Lobot helps with setting up and deploying Continuous Integration to AWS. He would love some feedback.

New Faces

Welcome Sean Beckett and Ash Hogan to the NY office.

Events

  • NYC.rb hackfest (Tuesday 24th)
  • Hope to see everyone at this weeks happy hour.

–

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (781)
  • rails (113)
  • testing (88)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (55)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (23)
  • mobile (22)
  • process (21)
  • pivotal tracker (21)
  • cucumber (20)
  • design (19)
  • jasmine (19)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • tracker ecosystem (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • css (13)
  • tdd (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to Community Feed
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >