scamp 1.2.0 → 2.0.0.pre
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.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/README.md +41 -128
- data/examples/v2.rb +39 -0
- data/lib/scamp/adapter.rb +47 -0
- data/lib/scamp/matcher.rb +15 -91
- data/lib/scamp/matches.rb +22 -0
- data/lib/scamp/message.rb +39 -0
- data/lib/scamp/plugin.rb +33 -0
- data/lib/scamp/version.rb +1 -1
- data/lib/scamp.rb +33 -43
- data/scamp.gemspec +9 -10
- data/spec/lib/adapter_spec.rb +145 -0
- data/spec/lib/matcher_spec.rb +122 -0
- data/spec/lib/matches_spec.rb +29 -0
- data/spec/lib/message_spec.rb +52 -0
- data/spec/lib/plugin_spec.rb +33 -0
- data/spec/lib/scamp_spec.rb +119 -659
- data/spec/spec_helper.rb +23 -1
- metadata +55 -58
- data/examples/bot.rb +0 -72
- data/lib/scamp/action.rb +0 -70
- data/lib/scamp/connection.rb +0 -32
- data/lib/scamp/messages.rb +0 -35
- data/lib/scamp/rooms.rb +0 -116
- data/lib/scamp/users.rb +0 -51
    
        data/lib/scamp.rb
    CHANGED
    
    | @@ -1,31 +1,16 @@ | |
| 1 1 | 
             
            require 'eventmachine'
         | 
| 2 | 
            -
            require 'em-http-request'
         | 
| 3 | 
            -
            require 'yajl'
         | 
| 4 2 | 
             
            require "logger"
         | 
| 5 3 |  | 
| 6 4 | 
             
            require "scamp/version"
         | 
| 7 | 
            -
            require 'scamp/connection'
         | 
| 8 | 
            -
            require 'scamp/rooms'
         | 
| 9 | 
            -
            require 'scamp/users'
         | 
| 10 5 | 
             
            require 'scamp/matcher'
         | 
| 11 | 
            -
            require 'scamp/ | 
| 12 | 
            -
            require 'scamp/ | 
| 6 | 
            +
            require 'scamp/adapter'
         | 
| 7 | 
            +
            require 'scamp/plugin'
         | 
| 13 8 |  | 
| 14 9 | 
             
            class Scamp
         | 
| 15 | 
            -
               | 
| 16 | 
            -
              include Rooms
         | 
| 17 | 
            -
              include Users
         | 
| 18 | 
            -
              include Messages
         | 
| 10 | 
            +
              attr_accessor :adapters, :plugins, :matchers, :logger, :verbose, :first_match_only, :required_format, :strip_prefix
         | 
| 19 11 |  | 
| 20 | 
            -
               | 
| 21 | 
            -
                            :logger, :verbose, :first_match_only, :ignore_self, :required_prefix,
         | 
| 22 | 
            -
                            :rooms_to_join
         | 
| 23 | 
            -
             | 
| 24 | 
            -
              def initialize(options = {})
         | 
| 12 | 
            +
              def initialize(options = {}, &block)
         | 
| 25 13 | 
             
                options ||= {}
         | 
| 26 | 
            -
                raise ArgumentError, "You must pass an API key" unless options[:api_key]
         | 
| 27 | 
            -
                raise ArgumentError, "You must pass a subdomain" unless options[:subdomain]
         | 
| 28 | 
            -
             | 
| 29 14 | 
             
                options.each do |k,v|
         | 
| 30 15 | 
             
                  s = "#{k}="
         | 
| 31 16 | 
             
                  if respond_to?(s)
         | 
| @@ -34,31 +19,41 @@ class Scamp | |
| 34 19 | 
             
                    logger.warn "Scamp initialized with #{k.inspect} => #{v.inspect} but NO UNDERSTAND!"
         | 
| 35 20 | 
             
                  end
         | 
| 36 21 | 
             
                end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                @ | 
| 39 | 
            -
                @rooms = {}
         | 
| 40 | 
            -
                @user_cache = {}
         | 
| 41 | 
            -
                @room_cache = {}
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                @strip_prefix ||= true
         | 
| 42 24 | 
             
                @matchers ||= []
         | 
| 25 | 
            +
                @adapters ||= {}
         | 
| 26 | 
            +
                @plugins  ||= []
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                yield self
         | 
| 43 29 | 
             
              end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
              def  | 
| 46 | 
            -
                 | 
| 30 | 
            +
             | 
| 31 | 
            +
              def adapter name, klass, opts={}
         | 
| 32 | 
            +
                adapter = klass.new self, opts
         | 
| 33 | 
            +
                sid = adapter.subscribe do |context, msg|
         | 
| 34 | 
            +
                  process_message(name, context, msg)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                @adapters[name] = {:adapter => adapter, :sid => sid}
         | 
| 47 37 | 
             
              end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
              def  | 
| 50 | 
            -
                 | 
| 51 | 
            -
                connect(api_key, room_list, &blk)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              def plugin klass, opts={}
         | 
| 40 | 
            +
                plugins << klass.new(self, opts)
         | 
| 52 41 | 
             
              end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
              def  | 
| 55 | 
            -
                 | 
| 42 | 
            +
             | 
| 43 | 
            +
              def connect!
         | 
| 44 | 
            +
                EM.run do
         | 
| 45 | 
            +
                  @adapters.each do |name, data|
         | 
| 46 | 
            +
                    logger.info "Connecting to #{name} adapter"
         | 
| 47 | 
            +
                    data[:adapter].connect!
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 56 50 | 
             
              end
         | 
| 57 51 |  | 
| 58 52 | 
             
              def logger
         | 
| 59 53 | 
             
                unless @logger
         | 
| 60 54 | 
             
                  @logger = Logger.new(STDOUT)
         | 
| 61 55 | 
             
                  @logger.level = (verbose ? Logger::DEBUG : Logger::INFO)
         | 
| 56 | 
            +
                  @logger.info "Scamp using default logger as none was provided"
         | 
| 62 57 | 
             
                end
         | 
| 63 58 | 
             
                @logger
         | 
| 64 59 | 
             
              end
         | 
| @@ -73,18 +68,13 @@ class Scamp | |
| 73 68 | 
             
                @first_match_only
         | 
| 74 69 | 
             
              end
         | 
| 75 70 |  | 
| 76 | 
            -
              private
         | 
| 77 | 
            -
             | 
| 78 71 | 
             
              def match trigger, params={}, &block
         | 
| 79 | 
            -
                params  | 
| 80 | 
            -
                matchers << Matcher.new(self, {:trigger => trigger, :action => block, :conditions => params[:conditions], :required_prefix => required_prefix})
         | 
| 72 | 
            +
                matchers << Matcher.new(self, {:trigger => trigger, :action => block, :on => params[:on], :conditions => params[:conditions]})
         | 
| 81 73 | 
             
              end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
              def process_message(msg)
         | 
| 84 | 
            -
                logger.debug "Received message #{msg.inspect}"
         | 
| 85 | 
            -
                return false if ignore_self && is_me?(msg[:user_id])
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              def process_message(channel, context, msg)
         | 
| 86 76 | 
             
                matchers.each do |matcher|
         | 
| 87 | 
            -
                  break if first_match_only & matcher.attempt(msg)
         | 
| 77 | 
            +
                  break if first_match_only & matcher.attempt(channel, context, msg)
         | 
| 88 78 | 
             
                end
         | 
| 89 79 | 
             
              end
         | 
| 90 80 | 
             
            end
         | 
    
        data/scamp.gemspec
    CHANGED
    
    | @@ -5,8 +5,8 @@ require "scamp/version" | |
| 5 5 | 
             
            Gem::Specification.new do |s|
         | 
| 6 6 | 
             
              s.name        = "scamp"
         | 
| 7 7 | 
             
              s.version     = Scamp::VERSION
         | 
| 8 | 
            -
              s.authors     = ["Will Jessop"]
         | 
| 9 | 
            -
              s.email       = ["will@willj.net"]
         | 
| 8 | 
            +
              s.authors     = ["Will Jessop", "Adam Holt"]
         | 
| 9 | 
            +
              s.email       = ["will@willj.net", "me@adamholt.co.uk"]
         | 
| 10 10 | 
             
              s.homepage    = "https://github.com/wjessop/Scamp"
         | 
| 11 11 | 
             
              s.summary     = %q{Eventmachine based Campfire bot framework}
         | 
| 12 12 | 
             
              s.description = %q{Eventmachine based Campfire bot framework}
         | 
| @@ -15,13 +15,12 @@ Gem::Specification.new do |s| | |
| 15 15 | 
             
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 16 16 | 
             
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 17 17 | 
             
              s.require_paths = ["lib"]
         | 
| 18 | 
            -
              
         | 
| 19 | 
            -
              s.add_dependency('eventmachine', '~> 1.0.0.rc.4')
         | 
| 20 | 
            -
              s.add_dependency('yajl-ruby', '~> 1.1')
         | 
| 21 | 
            -
              s.add_dependency('em-http-request', '~> 1.0')
         | 
| 22 18 |  | 
| 23 | 
            -
              s. | 
| 24 | 
            -
             | 
| 25 | 
            -
              s.add_development_dependency " | 
| 26 | 
            -
              s.add_development_dependency " | 
| 19 | 
            +
              s.add_dependency 'eventmachine', '~> 1.0'
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              s.add_development_dependency "rake"
         | 
| 22 | 
            +
              s.add_development_dependency "rspec", '~> 2.11'
         | 
| 23 | 
            +
              s.add_development_dependency "mocha", '~> 0.12'
         | 
| 24 | 
            +
              s.add_development_dependency "webmock", '~> 1.8'
         | 
| 25 | 
            +
              s.add_development_dependency "simplecov"
         | 
| 27 26 | 
             
            end
         | 
| @@ -0,0 +1,145 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Scamp::Adapter do
         | 
| 4 | 
            +
              let(:bot) { stub }
         | 
| 5 | 
            +
              describe "#new" do
         | 
| 6 | 
            +
                it "creates a new adapter" do
         | 
| 7 | 
            +
                  adapter = Scamp::Adapter.new(bot)
         | 
| 8 | 
            +
                  adapter.should_not be_nil
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                it "accepts a hash of options" do
         | 
| 12 | 
            +
                  adapter = Scamp::Adapter.new(bot, :hello => "world")
         | 
| 13 | 
            +
                  adapter.should_not be_nil
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              describe ".matches_required_format?" do
         | 
| 18 | 
            +
                let(:adapter) { Scamp::Adapter.new(bot) }
         | 
| 19 | 
            +
                let(:bot) { stub(:required_format => nil) }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                describe "no requirement" do
         | 
| 22 | 
            +
                  it "matches required format" do
         | 
| 23 | 
            +
                    adapter.matches_required_format?("Hello").should be_true
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                describe "string requirement" do
         | 
| 28 | 
            +
                  let(:bot) { stub(:required_format => "Bot: ") }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  it "matches msg with correct prefix" do
         | 
| 31 | 
            +
                    adapter.matches_required_format?("Bot: Hello").should be_true
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  it "does not match msg with incorrect prefix" do
         | 
| 35 | 
            +
                    adapter.matches_required_format?("Not: Hello").should be_false
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                describe "regex requirement" do
         | 
| 40 | 
            +
                  let(:bot) { stub(:required_format => /^Bot: /) }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  it "matches msg with correct prefix" do
         | 
| 43 | 
            +
                    adapter.matches_required_format?("Bot: Hello").should be_true
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  it "does not match msg with incorrect prefix" do
         | 
| 47 | 
            +
                    adapter.matches_required_format?("Not: Hello").should be_false
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                describe "other requirement" do
         | 
| 52 | 
            +
                  let(:bot) { stub(:required_format => Object.new) }
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  it "raises an ArgumentError" do
         | 
| 55 | 
            +
                    expect {
         | 
| 56 | 
            +
                      adapter.matches_required_format?("Bot: Hello").should be_true
         | 
| 57 | 
            +
                    }.to raise_error(ArgumentError)
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              describe ".strip_prefix" do
         | 
| 63 | 
            +
                describe "with strip_prefix enabled" do
         | 
| 64 | 
            +
                  describe "with a string require_format" do
         | 
| 65 | 
            +
                    let(:adapter) { Scamp::Adapter.new(bot) }
         | 
| 66 | 
            +
                    let(:bot) { stub(:required_format => "Bot: ", :strip_prefix => true) }
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    it "should strip the required_format if it is a string" do
         | 
| 69 | 
            +
                      adapter.strip_prefix("Bot: Hello").should == "Hello"
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    it "should not strip an incorrect prefix" do
         | 
| 73 | 
            +
                      adapter.strip_prefix("Not: Hello").should == "Not: Hello"
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  describe "with a Regex require_format" do
         | 
| 78 | 
            +
                    let(:adapter) { Scamp::Adapter.new(bot) }
         | 
| 79 | 
            +
                    let(:bot) { stub(:required_format => /^Bot: /, :strip_prefix => true) }
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                    it "should strip the required_format if it is a string" do
         | 
| 82 | 
            +
                      adapter.strip_prefix("Bot: Hello").should == "Bot: Hello"
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                    it "should not strip an incorrect prefix" do
         | 
| 86 | 
            +
                      adapter.strip_prefix("Not: Hello").should == "Not: Hello"
         | 
| 87 | 
            +
                    end
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                describe "with strip_prefix disabled" do
         | 
| 92 | 
            +
                  let(:adapter) { Scamp::Adapter.new(bot) }
         | 
| 93 | 
            +
                  let(:bot) { stub(:required_format => "Bot: ", :strip_prefix => false) }
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  it "should strip the required_format if it is a string" do
         | 
| 96 | 
            +
                    adapter.strip_prefix("Bot: Hello").should == "Bot: Hello"
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  it "should not strip an incorrect prefix" do
         | 
| 100 | 
            +
                    adapter.strip_prefix("Not: Hello").should == "Not: Hello"
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
              describe "channels" do
         | 
| 106 | 
            +
                let(:adapter) { Scamp::Adapter.new(bot) }
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                describe ".push" do
         | 
| 109 | 
            +
                  it "should push through the correct value" do
         | 
| 110 | 
            +
                    EM.run_block do
         | 
| 111 | 
            +
                      value = nil
         | 
| 112 | 
            +
                      adapter.subscribe do |msg|
         | 
| 113 | 
            +
                        value = msg
         | 
| 114 | 
            +
                      end
         | 
| 115 | 
            +
                      adapter.push "Hello World"
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                      value.should == "Hello World"
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                describe ".subscribe" do
         | 
| 123 | 
            +
                  it "allows subscriptions" do
         | 
| 124 | 
            +
                    EM.run_block do
         | 
| 125 | 
            +
                      subscribed = false
         | 
| 126 | 
            +
                      adapter.subscribe do |msg|
         | 
| 127 | 
            +
                        subscribed = true
         | 
| 128 | 
            +
                      end
         | 
| 129 | 
            +
                      adapter.push true
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                      subscribed.should be_true
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
              end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
              describe ".connect!" do
         | 
| 138 | 
            +
                let(:adapter) { Scamp::Adapter.new(bot) }
         | 
| 139 | 
            +
                it "should raise an implementation error" do
         | 
| 140 | 
            +
                  expect {
         | 
| 141 | 
            +
                    adapter.connect!
         | 
| 142 | 
            +
                  }.to raise_error(NotImplementedError)
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
              end
         | 
| 145 | 
            +
            end
         | 
| @@ -0,0 +1,122 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Scamp::Matcher do
         | 
| 4 | 
            +
              describe "#new" do
         | 
| 5 | 
            +
                let(:bot) { stub(adapters: {one: "two"}) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                it "requires a trigger" do
         | 
| 8 | 
            +
                  expect {
         | 
| 9 | 
            +
                    Scamp::Matcher.new(bot, action: ->(ctx, msg){})
         | 
| 10 | 
            +
                  }.to raise_error(ArgumentError)
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                it "requires a action" do
         | 
| 14 | 
            +
                  expect {
         | 
| 15 | 
            +
                    Scamp::Matcher.new(bot, trigger: "Hello")
         | 
| 16 | 
            +
                  }.to raise_error(ArgumentError)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              describe ".attempt" do
         | 
| 21 | 
            +
                context "channels" do
         | 
| 22 | 
            +
                  let(:msg) { Scamp::Message.new stub, body: "hello" }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  context "listened" do
         | 
| 25 | 
            +
                    it "runs the action when" do
         | 
| 26 | 
            +
                      result = false
         | 
| 27 | 
            +
                      matcher = Scamp::Matcher.new stub,
         | 
| 28 | 
            +
                                                     on: [:one],
         | 
| 29 | 
            +
                                                trigger: "hello",
         | 
| 30 | 
            +
                                                 action: ->(ctx, msg){result = true}
         | 
| 31 | 
            +
                      matcher.attempt(:one, stub, msg)
         | 
| 32 | 
            +
                      result.should be_true
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  context "unlistened" do
         | 
| 37 | 
            +
                    it "does not run the action" do
         | 
| 38 | 
            +
                      result = false
         | 
| 39 | 
            +
                      matcher = Scamp::Matcher.new stub,
         | 
| 40 | 
            +
                                                     on: [:one],
         | 
| 41 | 
            +
                                                trigger: "hello",
         | 
| 42 | 
            +
                                                 action: ->(ctx, msg){result = true}
         | 
| 43 | 
            +
                      matcher.attempt(:two, stub, msg)
         | 
| 44 | 
            +
                      result.should be_false
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                context "triggers" do
         | 
| 50 | 
            +
                  context "matching" do
         | 
| 51 | 
            +
                    it "runs the action" do
         | 
| 52 | 
            +
                      result = false
         | 
| 53 | 
            +
                      matcher = Scamp::Matcher.new stub,
         | 
| 54 | 
            +
                                                     on: [:one],
         | 
| 55 | 
            +
                                                trigger: "hello",
         | 
| 56 | 
            +
                                                 action: ->(ctx, msg){result = true}
         | 
| 57 | 
            +
                      msg = Scamp::Message.new stub, body: "hello"
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                      matcher.attempt(:one, stub, msg)
         | 
| 60 | 
            +
                      result.should be_true
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  context "non matching" do
         | 
| 65 | 
            +
                    it "runs the action" do
         | 
| 66 | 
            +
                      result = false
         | 
| 67 | 
            +
                      matcher = Scamp::Matcher.new stub,
         | 
| 68 | 
            +
                                                     on: [:one],
         | 
| 69 | 
            +
                                                trigger: "hello",
         | 
| 70 | 
            +
                                                 action: ->(ctx, msg){result = true}
         | 
| 71 | 
            +
                      msg = Scamp::Message.new stub, body: "goodbye"
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                      matcher.attempt(:one, stub, msg)
         | 
| 74 | 
            +
                      result.should be_false
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                context "validations" do
         | 
| 80 | 
            +
                  let(:message_class) {
         | 
| 81 | 
            +
                    class MyMessage < Scamp::Message
         | 
| 82 | 
            +
                      def valid?(conditions)
         | 
| 83 | 
            +
                        conditions[:hello] == "world"
         | 
| 84 | 
            +
                      end
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                    MyMessage
         | 
| 87 | 
            +
                  }
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  context "valid message" do
         | 
| 90 | 
            +
                    it "runs the action" do
         | 
| 91 | 
            +
                      result = false
         | 
| 92 | 
            +
                      matcher = Scamp::Matcher.new stub,
         | 
| 93 | 
            +
                                                     on: [:one],
         | 
| 94 | 
            +
                                                trigger: "hello",
         | 
| 95 | 
            +
                                                 action: ->(ctx, msg){result = true},
         | 
| 96 | 
            +
                                             conditions: {hello: "world"}
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                      msg = message_class.new stub, body: "hello"
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                      matcher.attempt(:one, stub, msg)
         | 
| 101 | 
            +
                      result.should be_true
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  context "invalid message" do
         | 
| 106 | 
            +
                    it "runs the action" do
         | 
| 107 | 
            +
                      result = false
         | 
| 108 | 
            +
                      matcher = Scamp::Matcher.new stub,
         | 
| 109 | 
            +
                                                     on: [:one],
         | 
| 110 | 
            +
                                                trigger: "hello",
         | 
| 111 | 
            +
                                                 action: ->(ctx, msg){result = true},
         | 
| 112 | 
            +
                                             conditions: {hello: "goodbye"}
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                      msg = message_class.new stub, body: "hello"
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                      matcher.attempt(:one, stub, msg)
         | 
| 117 | 
            +
                      result.should be_false
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
            end
         | 
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Scamp::Matches do
         | 
| 4 | 
            +
              let(:msg) { "Name: Scamp, URL: https://github.com/wjessop/Scamp/" }
         | 
| 5 | 
            +
              let(:match) { msg.match(/^Name: (?<name>\w+), URL: (?<url>.*)/) }
         | 
| 6 | 
            +
              let(:matches) { Scamp::Matches.new(match) }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              it "exposes the name from the capture" do
         | 
| 9 | 
            +
                matches.name.should eql("Scamp")
         | 
| 10 | 
            +
                matches[0].should eql("Scamp")
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              it "exposes the url from the capture" do
         | 
| 14 | 
            +
                matches.url.should eql("https://github.com/wjessop/Scamp/")
         | 
| 15 | 
            +
                matches[1].should eql("https://github.com/wjessop/Scamp/")
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              describe '.each' do
         | 
| 19 | 
            +
                it "iterates over each match" do
         | 
| 20 | 
            +
                  results = []
         | 
| 21 | 
            +
                  matches.each do |match|
         | 
| 22 | 
            +
                    results << match
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  results.should include("Scamp")
         | 
| 26 | 
            +
                  results.should include("https://github.com/wjessop/Scamp/")
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Scamp::Message do
         | 
| 4 | 
            +
              describe "#new" do
         | 
| 5 | 
            +
                it "should store and provide access to metadata" do
         | 
| 6 | 
            +
                  msg = Scamp::Message.new("foo", body: "hello", foo: "foo", bar: "bar")
         | 
| 7 | 
            +
                  msg.foo.should eql("foo")
         | 
| 8 | 
            +
                  msg.bar.should eql("bar")
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                it "should maintain metadata integrity when multiple instances exist" do
         | 
| 12 | 
            +
                  msg = Scamp::Message.new("foo", body: "hello", foo: "foo")
         | 
| 13 | 
            +
                  msg2 = Scamp::Message.new("foo", body: "hello", foo: "ouchie")
         | 
| 14 | 
            +
                  msg.foo.should eql("foo")
         | 
| 15 | 
            +
                  msg.foo.should eql("foo")
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                it "should isolate data access message instances created by different adapters" do
         | 
| 19 | 
            +
                  msg = Scamp::Message.new("foo", body: "hello", foo: "foo")
         | 
| 20 | 
            +
                  msg2 = Scamp::Message.new("foo2", body: "hello", bar: "bar")
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  msg.should respond_to(:foo)
         | 
| 23 | 
            +
                  msg.should_not respond_to(:bar)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  msg2.should respond_to(:bar)
         | 
| 26 | 
            +
                  msg2.should_not respond_to(:foo)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              describe ".valid?" do
         | 
| 31 | 
            +
                it "returns true by default" do
         | 
| 32 | 
            +
                  msg = Scamp::Message.new('foo', body: "hello")
         | 
| 33 | 
            +
                  msg.valid?(nil).should be_true
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              describe ".matches?" do
         | 
| 38 | 
            +
                let(:msg) { Scamp::Message.new('foo', body: "hello") }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it "matches a string trigger" do
         | 
| 41 | 
            +
                  msg.matches?("hello").should be_true
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it "matches a regex trigger" do
         | 
| 45 | 
            +
                  msg.matches?(/^hello$/).should be_true
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                it "does not match an invalid matcher" do
         | 
| 49 | 
            +
                  msg.matches?("goodbye").should be_false
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Scamp::Plugin do
         | 
| 4 | 
            +
              describe "#matchers" do
         | 
| 5 | 
            +
                it "is empty by default" do
         | 
| 6 | 
            +
                  Scamp::Plugin.matchers.should be_empty
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                it "should add a new matcher" do
         | 
| 10 | 
            +
                  expect {
         | 
| 11 | 
            +
                    Scamp::Plugin.match "Hello", :method
         | 
| 12 | 
            +
                  }.to change { Scamp::Plugin.matchers.size }.by(1)
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                describe ".new" do
         | 
| 16 | 
            +
                  let(:bot) { mock }
         | 
| 17 | 
            +
                  let(:plugin) { 
         | 
| 18 | 
            +
                    class TestPlugin < Scamp::Plugin
         | 
| 19 | 
            +
                      match "Hello", :name
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      def name(context, msg)
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                    TestPlugin
         | 
| 25 | 
            +
                  }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  it "attaches matchers to the bot" do
         | 
| 28 | 
            +
                    bot.expects(:match).with("Hello", {:on => nil}).once
         | 
| 29 | 
            +
                    plugin.new(bot)
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         |