pushpop 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +72 -0
- data/LICENSE +21 -0
- data/Procfile +1 -0
- data/README.md +582 -0
- data/Rakefile +48 -0
- data/jobs/example_job.rb +20 -0
- data/lib/plugins/keen.rb +78 -0
- data/lib/plugins/sendgrid.rb +94 -0
- data/lib/plugins/twilio.rb +52 -0
- data/lib/pushpop.rb +55 -0
- data/lib/pushpop/job.rb +95 -0
- data/lib/pushpop/step.rb +50 -0
- data/lib/pushpop/version.rb +3 -0
- data/pushpop.gemspec +22 -0
- data/spec/jobs/simple_job.rb +9 -0
- data/spec/plugins/keen_spec.rb +88 -0
- data/spec/plugins/sendgrid_spec.rb +66 -0
- data/spec/pushpop/job_spec.rb +147 -0
- data/spec/pushpop/step_spec.rb +78 -0
- data/spec/pushpop_spec.rb +24 -0
- data/spec/simple_job_spec.rb +9 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/templates/spec.html.erb +6 -0
- data/templates/first_template.html.erb +1 -0
- metadata +113 -0
    
        data/lib/pushpop/step.rb
    ADDED
    
    | @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            require 'erb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Pushpop
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              class Step
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                TEMPLATES_DIRECTORY = File.expand_path('../../../templates', __FILE__)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                class ERBContext
         | 
| 10 | 
            +
                  attr_accessor :response
         | 
| 11 | 
            +
                  attr_accessor :step_responses
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def initialize(response, step_responses)
         | 
| 14 | 
            +
                    self.response = response
         | 
| 15 | 
            +
                    self.step_responses = step_responses
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def get_binding
         | 
| 19 | 
            +
                    binding
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                attr_accessor :name
         | 
| 24 | 
            +
                attr_accessor :plugin
         | 
| 25 | 
            +
                attr_accessor :block
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def initialize(name=nil, plugin=nil, &block)
         | 
| 28 | 
            +
                  self.name = name || plugin || Pushpop.random_name
         | 
| 29 | 
            +
                  self.plugin = plugin
         | 
| 30 | 
            +
                  self.block = block
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def template(filename, response, step_responses={}, directory=TEMPLATES_DIRECTORY)
         | 
| 34 | 
            +
                  erb_context = ERBContext.new(response, step_responses)
         | 
| 35 | 
            +
                  ERB.new(get_template_contents(filename, directory)).result(erb_context.get_binding)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def run(last_response=nil, step_responses=nil)
         | 
| 39 | 
            +
                  self.instance_exec(last_response, step_responses, &block)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                private
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def get_template_contents(filename, directory)
         | 
| 45 | 
            +
                  File.read(File.join(directory, filename))
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            end
         | 
    
        data/pushpop.gemspec
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
            $:.push File.expand_path("../lib", __FILE__)
         | 
| 3 | 
            +
            require 'pushpop/version'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |s|
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              s.name        = "pushpop"
         | 
| 8 | 
            +
              s.version     = Pushpop::VERSION
         | 
| 9 | 
            +
              s.authors     = ["Josh Dzielak"]
         | 
| 10 | 
            +
              s.email       = "josh@keen.io"
         | 
| 11 | 
            +
              s.homepage    = "https://github.com/keenlabs/pushpop"
         | 
| 12 | 
            +
              s.summary     = "Automatic delivery of reports and alerts based on Keen IO events"
         | 
| 13 | 
            +
              s.description = "Pushpop is a simple but powerful Ruby app that sends notifications based on events captured with Keen IO."
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              s.add_dependency "clockwork"
         | 
| 16 | 
            +
              s.add_dependency "keen"
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              s.files         = `git ls-files`.split("\n")
         | 
| 19 | 
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 20 | 
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 21 | 
            +
              s.require_paths = ["lib"]
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,88 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Pushpop::Keen do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              describe '#configure' do
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                it 'should set various params' do
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  step = Pushpop::Keen.new do
         | 
| 10 | 
            +
                    event_collection 'pageviews'
         | 
| 11 | 
            +
                    analysis_type 'count'
         | 
| 12 | 
            +
                    timeframe 'last_3_days'
         | 
| 13 | 
            +
                    target_property 'trinkets'
         | 
| 14 | 
            +
                    group_by 'referer'
         | 
| 15 | 
            +
                    interval 'hourly'
         | 
| 16 | 
            +
                    filters [{ property_value: 'referer',
         | 
| 17 | 
            +
                               operator: 'ne',
         | 
| 18 | 
            +
                               property_value: 'yahoo.com' }]
         | 
| 19 | 
            +
                    steps [{ event_collection: 'pageviews',
         | 
| 20 | 
            +
                             actor_property: 'user.id' }]
         | 
| 21 | 
            +
                    analyses [{ analysis_type: 'count' }]
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  step.configure
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  step._event_collection.should == 'pageviews'
         | 
| 27 | 
            +
                  step._analysis_type.should == 'count'
         | 
| 28 | 
            +
                  step._timeframe.should == 'last_3_days'
         | 
| 29 | 
            +
                  step._group_by.should == 'referer'
         | 
| 30 | 
            +
                  step._interval.should == 'hourly'
         | 
| 31 | 
            +
                  step._steps.should == [{
         | 
| 32 | 
            +
                     event_collection: 'pageviews',
         | 
| 33 | 
            +
                     actor_property: 'user.id'
         | 
| 34 | 
            +
                    }]
         | 
| 35 | 
            +
                  step._analyses.should == [{ analysis_type: 'count' }]
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              describe '#run' do
         | 
| 41 | 
            +
                it 'should run the query based on the analysis type' do
         | 
| 42 | 
            +
                  Keen.stub(:count).with('pageviews', {
         | 
| 43 | 
            +
                      timeframe: 'last_3_days'
         | 
| 44 | 
            +
                  }).and_return(365)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  step = Pushpop::Keen.new('one') do
         | 
| 47 | 
            +
                    event_collection 'pageviews'
         | 
| 48 | 
            +
                    analysis_type 'count'
         | 
| 49 | 
            +
                    timeframe 'last_3_days'
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
                  response = step.run
         | 
| 52 | 
            +
                  response.should == 365
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              describe '#to_analysis_options' do
         | 
| 57 | 
            +
                it 'should include various options' do
         | 
| 58 | 
            +
                  step = Pushpop::Keen.new('one') do end
         | 
| 59 | 
            +
                  step._timeframe = 'last_4_days'
         | 
| 60 | 
            +
                  step._group_by = 'referer'
         | 
| 61 | 
            +
                  step._target_property = 'trinkets'
         | 
| 62 | 
            +
                  step._interval = 'hourly'
         | 
| 63 | 
            +
                  step._filters = [{ property_value: 'referer',
         | 
| 64 | 
            +
                                     operator: 'ne',
         | 
| 65 | 
            +
                                     property_value: 'yahoo.com' }]
         | 
| 66 | 
            +
                  step._steps = [{ event_collection: 'pageviews',
         | 
| 67 | 
            +
                                   actor_property: 'user.id' }]
         | 
| 68 | 
            +
                  step._analyses = [{ analysis_type: 'count' }]
         | 
| 69 | 
            +
                  step.to_analysis_options.should == {
         | 
| 70 | 
            +
                      timeframe: 'last_4_days',
         | 
| 71 | 
            +
                      target_property: 'trinkets',
         | 
| 72 | 
            +
                      group_by: 'referer',
         | 
| 73 | 
            +
                      interval: 'hourly',
         | 
| 74 | 
            +
                      filters: [{ property_value: 'referer',
         | 
| 75 | 
            +
                                     operator: 'ne',
         | 
| 76 | 
            +
                                     property_value: 'yahoo.com' }],
         | 
| 77 | 
            +
                      steps: [{ event_collection: 'pageviews',
         | 
| 78 | 
            +
                                   actor_property: 'user.id' }],
         | 
| 79 | 
            +
                      analyses: [{ analysis_type: 'count' }]
         | 
| 80 | 
            +
                  }
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                it 'should not include nils' do
         | 
| 84 | 
            +
                  step = Pushpop::Keen.new('one') do end
         | 
| 85 | 
            +
                  step.to_analysis_options.should == {}
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
            end
         | 
| @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            SPEC_TEMPLATES_DIRECTORY ||= File.expand_path('../../templates', __FILE__)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe Pushpop::Sendgrid do
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              describe '#configure' do
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                it 'should set various params' do
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  step = Pushpop::Sendgrid.new do
         | 
| 12 | 
            +
                    to 'josh@keen.io'
         | 
| 13 | 
            +
                    from 'depths@hell.com'
         | 
| 14 | 
            +
                    subject 'time is up'
         | 
| 15 | 
            +
                    body 'use code 3:16 for high leniency'
         | 
| 16 | 
            +
                    preview true
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  step.configure
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  step._to.should == 'josh@keen.io'
         | 
| 22 | 
            +
                  step._from.should == 'depths@hell.com'
         | 
| 23 | 
            +
                  step._subject.should == 'time is up'
         | 
| 24 | 
            +
                  step._body.should == 'use code 3:16 for high leniency'
         | 
| 25 | 
            +
                  step._preview.should be_true
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              describe '#run' do
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                it 'should send some email' do
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  Mail.stub(:deliver)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  step = Pushpop::Sendgrid.new do |response|
         | 
| 38 | 
            +
                    to 'josh@keen.io'
         | 
| 39 | 
            +
                    from 'alerts+pushpop@keen.io'
         | 
| 40 | 
            +
                    subject "There were #{response} Pageviews Today!"
         | 
| 41 | 
            +
                    body 'hey wats up'
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  step.run(365)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              describe '#body' do
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                it 'should use a string if given 1 arg' do
         | 
| 53 | 
            +
                  step = Pushpop::Sendgrid.new
         | 
| 54 | 
            +
                  step.body 'hello world'
         | 
| 55 | 
            +
                  step._body.should == 'hello world'
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it 'should use a template if more than 1 arg is passed' do
         | 
| 59 | 
            +
                  step = Pushpop::Sendgrid.new
         | 
| 60 | 
            +
                  step.body('spec.html.erb', 500, {}, SPEC_TEMPLATES_DIRECTORY)
         | 
| 61 | 
            +
                  step._body.strip.should == '<pre>500</pre>'
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            end
         | 
| @@ -0,0 +1,147 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Pushpop::Job do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let (:empty_job) { Pushpop::Job.new('foo') do end }
         | 
| 6 | 
            +
              let (:empty_step) { Pushpop::Step.new('bar') do end }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              describe '#register_plugins' do
         | 
| 9 | 
            +
                it 'should register a plugin' do
         | 
| 10 | 
            +
                  Pushpop::Job.register_plugin('blaz', Class)
         | 
| 11 | 
            +
                  Pushpop::Job.plugins['blaz'].should == Class
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              describe '#initialize' do
         | 
| 16 | 
            +
                it 'should set a name and evaluate a block' do
         | 
| 17 | 
            +
                  block_ran = false
         | 
| 18 | 
            +
                  job = Pushpop::Job.new('foo') do block_ran = true end
         | 
| 19 | 
            +
                  job.name.should == 'foo'
         | 
| 20 | 
            +
                  job.every_duration.should be_nil
         | 
| 21 | 
            +
                  job.every_options.should == {}
         | 
| 22 | 
            +
                  block_ran.should be_true
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                it 'should auto-generate a name' do
         | 
| 26 | 
            +
                  job = Pushpop::Job.new do end
         | 
| 27 | 
            +
                  job.name.should_not be_nil
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              describe '#every' do
         | 
| 32 | 
            +
                it 'should set duration and options' do
         | 
| 33 | 
            +
                  job = empty_job
         | 
| 34 | 
            +
                  job.every(10.seconds, at: '01:02')
         | 
| 35 | 
            +
                  job.every_duration.should == 10
         | 
| 36 | 
            +
                  job.every_options.should == { at: '01:02' }
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              describe '#step' do
         | 
| 41 | 
            +
                it 'should add the step to the internal list of steps' do
         | 
| 42 | 
            +
                  empty_proc = Proc.new {}
         | 
| 43 | 
            +
                  job = empty_job
         | 
| 44 | 
            +
                  job.step('blah', &empty_proc)
         | 
| 45 | 
            +
                  job.steps.first.name.should == 'blah'
         | 
| 46 | 
            +
                  job.steps.first.block.should == empty_proc
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                context 'plugin specified' do
         | 
| 50 | 
            +
                  class FakeStep < Pushpop::Step
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  before do
         | 
| 54 | 
            +
                    Pushpop::Job.register_plugin('blaz', FakeStep)
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  it 'should use the registered plugin to instantiate the class' do
         | 
| 58 | 
            +
                    empty_proc = Proc.new {}
         | 
| 59 | 
            +
                    job = empty_job
         | 
| 60 | 
            +
                    job.step('blah', 'blaz', &empty_proc)
         | 
| 61 | 
            +
                    job.steps.first.name.should == 'blah'
         | 
| 62 | 
            +
                    job.steps.first.plugin.should == 'blaz'
         | 
| 63 | 
            +
                    job.steps.first.class.should == FakeStep
         | 
| 64 | 
            +
                    job.steps.first.block.should == empty_proc
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  it 'should throw an exception for an unregistered plugin' do
         | 
| 68 | 
            +
                    empty_proc = Proc.new {}
         | 
| 69 | 
            +
                    job = empty_job
         | 
| 70 | 
            +
                    expect {
         | 
| 71 | 
            +
                      job.step('blah', 'blaze', &empty_proc)
         | 
| 72 | 
            +
                    }.to raise_error /No plugin configured/
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              describe '#run' do
         | 
| 78 | 
            +
                it 'should call each step with the response to the previous' do
         | 
| 79 | 
            +
                  job = Pushpop::Job.new('foo') do
         | 
| 80 | 
            +
                    step 'one' do
         | 
| 81 | 
            +
                      10
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    step 'two' do |response|
         | 
| 85 | 
            +
                      response + 20
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                  job.run.should == [30, { 'one' => 10, 'two' => 30 }]
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
              describe '#schedule' do
         | 
| 93 | 
            +
                it 'should add the job to clockwork' do
         | 
| 94 | 
            +
                  frequency = 1.seconds
         | 
| 95 | 
            +
                  simple_job = Pushpop::Job.new('foo') do
         | 
| 96 | 
            +
                    every frequency
         | 
| 97 | 
            +
                    step 'track_times_run' do
         | 
| 98 | 
            +
                      @times_run ||= 0
         | 
| 99 | 
            +
                      @times_run += 1
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  simple_job.schedule
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  Clockwork.manager.tick(Time.now)
         | 
| 106 | 
            +
                  simple_job.run.first.should == 2
         | 
| 107 | 
            +
                  Clockwork.manager.tick(Time.now + frequency)
         | 
| 108 | 
            +
                  simple_job.run.first.should == 4
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
              describe '#method_missing' do
         | 
| 113 | 
            +
                class FakeStep < Pushpop::Step
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                before do
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                it 'should assume its a registered plugin name and try to create a step' do
         | 
| 120 | 
            +
                  Pushpop::Job.register_plugin('blaz', FakeStep)
         | 
| 121 | 
            +
                  simple_job = job do
         | 
| 122 | 
            +
                    blaz 'hi' do end
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
                  simple_job.steps.first.name.should == 'hi'
         | 
| 125 | 
            +
                  simple_job.steps.first.class.should == FakeStep
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                it 'should not assume a name' do
         | 
| 129 | 
            +
                  Pushpop::Job.register_plugin('blaz', FakeStep)
         | 
| 130 | 
            +
                  simple_job = job do
         | 
| 131 | 
            +
                    blaz do end
         | 
| 132 | 
            +
                  end
         | 
| 133 | 
            +
                  simple_job.steps.first.name.should_not be_nil
         | 
| 134 | 
            +
                  simple_job.steps.first.plugin.should == 'blaz'
         | 
| 135 | 
            +
                  simple_job.steps.first.class.should == FakeStep
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                it 'should raise an exception if there is no registered plugin' do
         | 
| 139 | 
            +
                  expect {
         | 
| 140 | 
            +
                    job do
         | 
| 141 | 
            +
                      blaze do end
         | 
| 142 | 
            +
                    end
         | 
| 143 | 
            +
                  }.to raise_error /undefined method/
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            end
         | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            SPEC_TEMPLATES_DIRECTORY ||= File.expand_path('../../templates', __FILE__)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe Pushpop::Step do
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              describe 'initialize' do
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                it 'should set a name, a plugin, and a block' do
         | 
| 10 | 
            +
                  empty_proc = Proc.new {}
         | 
| 11 | 
            +
                  step = Pushpop::Step.new('foo', 'foopie', &empty_proc)
         | 
| 12 | 
            +
                  step.name.should == 'foo'
         | 
| 13 | 
            +
                  step.plugin.should == 'foopie'
         | 
| 14 | 
            +
                  step.block.should == empty_proc
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                it 'should auto-generate a name if not given and plugin not given' do
         | 
| 18 | 
            +
                  empty_proc = Proc.new {}
         | 
| 19 | 
            +
                  step = Pushpop::Step.new(&empty_proc)
         | 
| 20 | 
            +
                  step.name.should_not be_nil
         | 
| 21 | 
            +
                  step.plugin.should be_nil
         | 
| 22 | 
            +
                  step.block.should == empty_proc
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                it 'should set name to plugin name if not given' do
         | 
| 26 | 
            +
                  empty_proc = Proc.new {}
         | 
| 27 | 
            +
                  step = Pushpop::Step.new(nil, 'keen', &empty_proc)
         | 
| 28 | 
            +
                  step.name.should == 'keen'
         | 
| 29 | 
            +
                  step.plugin.should == 'keen'
         | 
| 30 | 
            +
                  step.block.should == empty_proc
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                it 'should not require a plugin' do
         | 
| 34 | 
            +
                  empty_proc = Proc.new {}
         | 
| 35 | 
            +
                  step = Pushpop::Step.new('foo', &empty_proc)
         | 
| 36 | 
            +
                  step.name.should == 'foo'
         | 
| 37 | 
            +
                  step.block.should == empty_proc
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              describe 'run' do
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it 'should call the block with the same args' do
         | 
| 45 | 
            +
                  arg1, arg2 = nil
         | 
| 46 | 
            +
                  times_run = 0
         | 
| 47 | 
            +
                  empty_proc = Proc.new { |a1, a2| arg1 = a1; arg2 = a2; times_run += 1 }
         | 
| 48 | 
            +
                  step = Pushpop::Step.new('foo', &empty_proc)
         | 
| 49 | 
            +
                  step.run('foo', 'bar')
         | 
| 50 | 
            +
                  arg1.should == 'foo'
         | 
| 51 | 
            +
                  arg2.should == 'bar'
         | 
| 52 | 
            +
                  times_run.should == 1
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                it 'should execute the block bound to the step' do
         | 
| 56 | 
            +
                  _self = nil
         | 
| 57 | 
            +
                  step = Pushpop::Step.new(nil, nil) do
         | 
| 58 | 
            +
                    _self = self
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                  step.run
         | 
| 61 | 
            +
                  _self.should == step
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              describe 'template' do
         | 
| 67 | 
            +
                it 'should render the named template with the response binding' do
         | 
| 68 | 
            +
                  step = Pushpop::Step.new
         | 
| 69 | 
            +
                  step.template('spec.html.erb', 500, {}, SPEC_TEMPLATES_DIRECTORY).strip.should == '<pre>500</pre>'
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                it 'should render the named template with the step_response binding' do
         | 
| 73 | 
            +
                  step = Pushpop::Step.new
         | 
| 74 | 
            +
                  step.template('spec.html.erb', nil, { test: 600 }, SPEC_TEMPLATES_DIRECTORY).strip.should == '<pre>600</pre>'
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            end
         |