Making assertions about a timeline of events more confident

60 views
Skip to first unread message

Anthony Green

unread,
Nov 21, 2013, 6:11:53 AM11/21/13
to objects-...@googlegroups.com
I'd like to apply some of the ideas I'm picking up from Confident Ruby to a test helper class I have to devise.

I have a timeline of events that originates in the browser via a JavaScript logger and arrives in ruby land as an array of hashes.

[ {type: "initialized"}, {type: "loadedPlaylist", url: "example.org/playlist"}, { type: 'playing' }, { type: 'paused' } ]

I would then like to make assertions on the behaviour of AUT based on the contents of the timeline

player.should have_loaded playlist

I've been using chained enumerators to find if an event exists and has the correct properties

timeline.select { |event| event[:type] == 'playlistLoaded' }.select { |event| event[:url] ==url }

but I have this feeling that there's probably a more confident approach

Anthony Green

unread,
Nov 22, 2013, 8:04:25 AM11/22/13
to objects-...@googlegroups.com
After a bit of thinking I've got this implementation:

class TimelineOfEvents
  
  attr_reader :events
  
  class Event < Struct
    
    def == other
      self.class == Object.const_get(String(other).capitalize)
    end
  end
  
  def initialize events
    @events = events.collect { |event| Event(event) }
  end
  
  def Event obj
    obj = obj.dup.downcase_keys!.symbolize_keys!
    klass_name = obj.delete(:type).capitalize
    if Object.const_defined?(klass_name)
      Object.const_get(klass_name).new(*obj.values)
    else
      klass = Object.const_set(klass_name, Event.new(*obj.keys))
      klass.new(*obj.values)
    end
  end
end

timeline = TimelineOfEvents.new([{ 'type' => 'playing', 'url' => 'example.org' }])

timeline.events.first == Playing


Eugene Kalenkovich

unread,
Nov 22, 2013, 11:46:10 AM11/22/13
to objects-...@googlegroups.com
I am not sure that your code became any more confident by moving of comparison of strings to comparison of classes.

You are also opening a security hole here - ajax events should be considered user input), so your approach requires additional level of input checking

Sorry that I am not giving any suggestions for different approaches - for this you'd have to describe your problem more precisely, At this moment your event and code examples are not consistent nor comprehensive enough to understand the problem

Anthony Green

unread,
Nov 23, 2013, 10:13:57 AM11/23/13
to objects-...@googlegroups.com


On Friday, 22 November 2013 16:46:10 UTC, Eugene Kalenkovich wrote:
I am not sure that your code became any more confident by moving of comparison of strings to comparison of classes.

Not as end point no, but I was seeing whether this direction would permit me to add more useful semantics in the next iteration.

Avdi Grimm

unread,
Nov 25, 2013, 6:04:12 PM11/25/13
to objects-...@googlegroups.com

On Thu, Nov 21, 2013 at 6:11 AM, Anthony Green <anthony.ch...@gmail.com> wrote:
timeline.select { |event| event[:type] == 'playlistLoaded' }.select { |event| event[:url] ==url }

I kinda like chained selects...


--
Avdi Grimm
http://avdi.org

I only check email twice a day. to reach me sooner, go to http://awayfind.com/avdi
Reply all
Reply to author
Forward
0 new messages