JackDanger-wave 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jack Danger Canty
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ # Wave
2
+
3
+ Ruby client for the Google Wave Federation Protocol
4
+
5
+ based on the [whitepapers](http://www.waveprotocol.org/whitepapers)
6
+ for use in building [robots](http://code.google.com/intl/it/apis/wave/extensions/robots/index.html) or
7
+ Ruby clients for human interaction.
8
+
9
+ Author: [Jack Danger Canty](http://jackcanty.com)
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "wave"
8
+ gem.summary = %Q{Ruby client for the Google Wave Federation Protocol}
9
+ gem.email = "google-wave@jackcanty.com"
10
+ gem.homepage = "http://github.com/JackDanger/wave"
11
+ gem.authors = ["Jack Danger Canty"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION.yml')
45
+ config = YAML.load(File.read('VERSION.yml'))
46
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "wave #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
@@ -0,0 +1,39 @@
1
+ # Wave
2
+ #
3
+ # A wave is identified by a globally unique wave id, which is
4
+ # a pair of a domain name and an id string. The domain names
5
+ # the wave provider where the wave originated.
6
+ # So if you're accessing a wave initiated by wave.google.com
7
+ # the Wave id may look like the following:
8
+ #
9
+ # a12f4d@wave.google.com
10
+ #
11
+ # A wave contains a collection of wavelets which each have a distinct
12
+ # list of participants and a historical set of operations (blips)
13
+ # which contain documents
14
+
15
+
16
+ class Wave
17
+ VERSION = File.read(File.dirname(__FILE__) + "/../VERSION").chomp
18
+
19
+ class WaveError < StandardError; end
20
+
21
+
22
+ attr_reader :id, :wavelets, :options
23
+
24
+ def initialize(id, options = {})
25
+ @id = id
26
+ @options = options
27
+ @wavelets = []
28
+ end
29
+ end
30
+
31
+
32
+ $:.unshift File.dirname(__FILE__)
33
+
34
+ require "wave/wavelet"
35
+ require "wave/participant"
36
+ require "wave/blip"
37
+ require "wave/document"
38
+ require "wave/annotation"
39
+ require "wave/robot"
@@ -0,0 +1,23 @@
1
+ # Annotation
2
+ #
3
+ # Documents have annotations that span a range of the
4
+ # document's length. An annotation is a key/value pair
5
+ # applied to some portion of the document.
6
+ #
7
+ #
8
+
9
+ class Wave
10
+ class Annotation
11
+
12
+ attr_reader :document, :name, :value, :range
13
+
14
+ def initialize(document, name, value, range = 0..0)
15
+ @document = document
16
+ @name = name
17
+ @value = value
18
+ @range = range
19
+ raise Wave::WaveError, "Annotation has no document" unless document
20
+ document.annotations << self
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ # Blip
2
+ #
3
+ # A blip is a historical operation performed on a wavelet. If the
4
+ # wavelet is a conversation then this is the smallest meaningful
5
+ # element of that conversation. Blips can be arranged in a tree
6
+ # structure with parent/child relationships and each wavelet has
7
+ # a 'root' blip that is considered the first element of the wavelet.
8
+ #
9
+ # Each blip contains a document which holds all the interesting
10
+ # content of the blip.
11
+ #
12
+
13
+ class Wave
14
+ class Blip
15
+
16
+ attr_reader :wavelet, :parent, :children, :creator
17
+ attr_accessor :document
18
+
19
+ def initialize(options = {})
20
+ if options[:parent]
21
+ @parent = options[:parent]
22
+ @parent.children << self
23
+ @wavelet = @parent.wavelet
24
+ end
25
+ @wavelet ||= options[:wavelet]
26
+ raise Wave::WaveError, "Blip has no wavelet" unless @wavelet
27
+ @creator = options[:creator]
28
+ raise Wave::WaveError, "Blip has no creator" unless @creator
29
+ @wavelet.blips << self
30
+ @children ||= []
31
+ end
32
+
33
+ def root?
34
+ self == wavelet.blips.first
35
+ end
36
+
37
+ def wave
38
+ wavelet.wave
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ # Document
2
+ #
3
+ # A document is attached to a blip and contains the interesting
4
+ # data for this element of the conversation.
5
+ #
6
+ # Documents contain annotations, elements and a serialized
7
+ #
8
+ #
9
+
10
+ class Wave
11
+ class Document
12
+
13
+ ELEMENT_TYPES = ['INLINE_BLIP', 'INPUT', 'CHECK', 'LABEL',
14
+ 'BUTTON', 'RADIO_BUTTON', 'RADIO_BUTTON_GROUP',
15
+ 'PASSWORD', 'GADGET', 'IMAGE']
16
+
17
+ attr_reader :blip, :elements, :annotations
18
+
19
+ def initialize(type, options = {})
20
+ @type = type
21
+ @blip = options.delete(:blip)
22
+ @options = options
23
+ @elements = []
24
+ @annotations = []
25
+ raise Wave::WaveError, "Document has no blip" unless blip
26
+ blip.document = self
27
+ end
28
+
29
+ def wavelet
30
+ blip.wavelet
31
+ end
32
+
33
+ def wave
34
+ wavelet.wave
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ class Wave
2
+ module Events
3
+
4
+ attr_reader :events
5
+
6
+ EVENTS = [
7
+ 'WAVELET_BLIP_CREATED',
8
+ 'WAVELET_BLIP_REMOVED',
9
+ 'WAVELET_PARTICIPANTS_CHANGED',
10
+ 'WAVELET_TIMESTAMP_CHANGED',
11
+ 'WAVELET_TITLE_CHANGED',
12
+ 'WAVELET_VERSION_CHANGED',
13
+ 'BLIP_CONTRIBUTORS_CHANGED',
14
+ 'BLIP_DELETED',
15
+ 'BLIP_SUBMITTED',
16
+ 'BLIP_TIMESTAMP_CHANGED',
17
+ 'BLIP_VERSION_CHANGED',
18
+ 'DOCUMENT_CHANGED',
19
+ 'FORM_BUTTON_CLICKED'
20
+ ]
21
+
22
+ EVENTS.each do |event|
23
+ eval <<-EOMETHOD
24
+ def #{event.downcase}(&block)
25
+ raise "No callback action defined for #{event}" unless block
26
+ add_callback_for(:#{event.downcase}, block)
27
+ end
28
+ EOMETHOD
29
+ end
30
+
31
+ protected
32
+
33
+ def add_callback_for(event, block)
34
+ @events ||= {}
35
+ @events[event] ||= []
36
+ @events[event] << block
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ # Participant
2
+ #
3
+ # A participant is one of the humans or robots that have full
4
+ # read/write access to a wavelet. Participants are identified
5
+ # by a unique id that (conveniently) is in the exact format of
6
+ # an email address.
7
+ #
8
+
9
+ class Wave
10
+ class Participant
11
+
12
+ attr_reader :wavelet, :id
13
+
14
+
15
+ def initialize(options = {})
16
+ @wavelet = options[:wavelet]
17
+ raise Wave::WaveError, "Participant requires wavelet" unless @wavelet
18
+ @wavelet.participants << self
19
+ @id = options[:id]
20
+ raise Wave::WaveError, "Participant requires id" unless @id
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,52 @@
1
+ #
2
+ # Wave Robot
3
+ #
4
+ # A wave robot is created by giving the robot a name
5
+ # and a set of options and then definining callbacks
6
+ # for the various operations it might receive from the
7
+ # wave server.
8
+ #
9
+ # For example:
10
+ # Robot.define "Terminator",
11
+ # :image_url => 'http://www.sky.net/models/t800.png',
12
+ # :profile_url => 'http://www.sky.net/models/t800.html'
13
+ # do |robot|
14
+ # robot.wavelet_participants_changed do |wavelet|
15
+ # wavelet.kill_participant
16
+ # end
17
+ # end
18
+ #
19
+ # Required options:
20
+ # image_url: the location of the avatar graphic to identify the robot
21
+ # profile_url: the URI of the html description of the robot.
22
+ # Available options:
23
+ # debug: Optional variable that defaults to False and is passed through
24
+ # to the webapp application to determine if it should show debug info.
25
+ #
26
+
27
+ require "wave/events"
28
+
29
+ class Wave
30
+ class Robot
31
+
32
+ class Error < StandardError; end
33
+
34
+ include Wave::Events
35
+
36
+ def self.define(name, options = {}, &block)
37
+ instance = new(name, options)
38
+ yield instance if block_given?
39
+ instance
40
+ end
41
+
42
+ attr_reader :name, :options
43
+
44
+ def initialize(name, options = {})
45
+ raise Error, "Each Robot requires a name" if name.empty?
46
+ raise Error, "Each Robot requires an image_url" unless options[:image_url]
47
+ raise Error, "Each Robot requires a profile_url" unless options[:profile_url]
48
+ @name = name
49
+ @options = options
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,29 @@
1
+ # Wavelet
2
+ #
3
+ # A wavelet has a list of participants that can be any mixture
4
+ # of humans or robots. This set of participants is distinct from
5
+ # the participants of any other wavelet in the wave.
6
+ # A wavelet also contains a set of 'blips' which are an ordered
7
+ # set of operations serving to create a history for the wavelet.
8
+ # These blips contain the documents that make up the real content
9
+ # of the wavelet.
10
+ #
11
+
12
+
13
+ class Wave
14
+ class Wavelet
15
+
16
+ attr_reader :wave, :options, :participants, :blips
17
+
18
+ def initialize(options = {})
19
+ raise Wave::WaveError,
20
+ "Wavelets must be instantiated with a wave option" unless
21
+ options[:wave] && options[:wave].is_a?(Wave)
22
+
23
+ @wave = options.delete(:wave)
24
+ @participants = options.delete(:participants) || []
25
+ @blips = options.delete(:blips) || []
26
+ @wave.wavelets << self
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class AnnotationTest < Test::Unit::TestCase
4
+
5
+ context "a annotation" do
6
+ setup { @annotation = Factory.annotation }
7
+ should "have a document" do
8
+ assert @annotation.document
9
+ end
10
+ should "have a name" do
11
+ assert @annotation.name
12
+ end
13
+ should "have a value" do
14
+ assert @annotation.value
15
+ end
16
+ should "have a range" do
17
+ assert @annotation.range
18
+ end
19
+ should "register itself as an annotation in its document" do
20
+ assert @annotation.document.annotations.include?(@annotation)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class BlipTest < Test::Unit::TestCase
4
+
5
+ context "a blip" do
6
+ setup { @blip = Factory.blip }
7
+ should "have a wavelet" do
8
+ assert @blip.wavelet
9
+ end
10
+ should "have a wave" do
11
+ assert @blip.wave
12
+ end
13
+ should "have a creator" do
14
+ assert @blip.creator
15
+ end
16
+ should "have a collection of child blips" do
17
+ assert @blip.children
18
+ end
19
+ should "be root if it's the first blip in the wavelet" do
20
+ assert @blip.root?
21
+ end
22
+ should "not have a parent if it's the root blip" do
23
+ assert !@blip.parent
24
+ end
25
+ should "register itself in its wavelet's blip collection" do
26
+ assert @blip.wavelet.blips.include?(@blip)
27
+ end
28
+ context "made second" do
29
+ setup { @second_blip = Factory.blip(:wavelet => @blip.wavelet) }
30
+ should "not be root" do
31
+ assert !@second_blip.root?
32
+ end
33
+ end
34
+ context "made as a child to another blip" do
35
+ setup { @child_blip = Factory.blip(:parent => @blip) }
36
+ should "not be root" do
37
+ assert !@child_blip.root?
38
+ end
39
+ should "have a proper parent blip" do
40
+ assert_equal @blip, @child_blip.parent
41
+ end
42
+ should "be in the parent blip's collection of children" do
43
+ assert @blip.children.include?(@child_blip)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class DocumentTest < Test::Unit::TestCase
4
+
5
+ context "a document" do
6
+ setup { @document = Factory.document }
7
+ should "have a blip" do
8
+ assert @document.blip
9
+ end
10
+ should "have a wavelet" do
11
+ assert @document.wavelet
12
+ end
13
+ should "have a wave" do
14
+ assert @document.wave
15
+ end
16
+ should "have a collection of annotations" do
17
+ assert @document.annotations
18
+ end
19
+ should "have a collection of non-text elements" do
20
+ assert @document.elements
21
+ end
22
+ should "register itself as its blip's document" do
23
+ assert_equal @document, @document.blip.document
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ParticipantTest < Test::Unit::TestCase
4
+
5
+ context "a participant" do
6
+ setup { @blip = Factory.participant }
7
+ should "have a wavelet" do
8
+ assert @blip.wavelet
9
+ end
10
+ should "have an id" do
11
+ assert @blip.id
12
+ end
13
+ should "require an id" do
14
+ assert_raises Wave::WaveError do
15
+ Wave::Participant.new(:wavelet => Factory.wavelet)
16
+ end
17
+ end
18
+ should "require a wavelet" do
19
+ assert_raises Wave::WaveError do
20
+ Wave::Participant.new(:id => 'user@email.com')
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class RobotTest < Test::Unit::TestCase
4
+
5
+ context "defining a robot" do
6
+ context "with no name" do
7
+ should "raise error" do
8
+ assert_raises(Wave::Robot::Error) { Wave::Robot.define '' }
9
+ end
10
+ end
11
+ context "with no options" do
12
+ should "raise error" do
13
+ assert_raises(Wave::Robot::Error) { Wave::Robot.define('PoorlyDefined') }
14
+ end
15
+ end
16
+ context "with name and options" do
17
+ setup {
18
+ @robot = Wave::Robot.define("ValidName", :image_url => '/img.jpg',
19
+ :profile_url => '/profile.html')
20
+ }
21
+ should "return a robot instance" do
22
+ assert_kind_of Wave::Robot, @robot
23
+ end
24
+ should "set the name on the robot" do
25
+ assert_equal 'ValidName', @robot.name
26
+ end
27
+ should "set the options on the robot" do
28
+ assert_equal '/img.jpg', @robot.options[:image_url]
29
+ assert_equal '/profile.html', @robot.options[:profile_url]
30
+ end
31
+ end
32
+ end
33
+
34
+ context "Robot events" do
35
+ context "specified via .define block" do
36
+ setup {
37
+ @robot =
38
+ Wave::Robot.define "ValidName",
39
+ :image_url => '/img.jpg',
40
+ :profile_url => '/prof.html' do |r|
41
+ r.wavelet_blip_created do |content|
42
+ "create a new blip"
43
+ end
44
+ r.wavelet_blip_removed do |content|
45
+ "remove the blip locally"
46
+ end
47
+ r.wavelet_blip_removed do |content|
48
+ "do something else after a blip is removed"
49
+ end
50
+ end
51
+ }
52
+ should "save the specified events into an event callback" do
53
+ assert_equal 1, @robot.events[:wavelet_blip_created].size
54
+ end
55
+ should "have no callbacks for events that weren't supplied" do
56
+ assert !@robot.events[:document_changed]
57
+ end
58
+ should "support multiple callbacks of the same type" do
59
+ assert_equal 2, @robot.events[:wavelet_blip_removed].size
60
+ end
61
+ should "catch typos on event names" do
62
+ assert_raises NoMethodError do
63
+ Wave::Robot.define "ValidName",
64
+ :image_url => '/img.jpg',
65
+ :profile_url => '/prof.html' do |r|
66
+ r.wildly_invalid_event_name {}
67
+ end
68
+ end
69
+ end
70
+ should "allow more events to be added after the initial block" do
71
+ @robot.wavelet_blip_created {|c| "freak out about the new blip" }
72
+ assert_equal 2, @robot.events[:wavelet_blip_created].size
73
+ end
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,70 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+
8
+ require 'wave'
9
+ class Test::Unit::TestCase
10
+ module Factory
11
+ class << self
12
+
13
+ def wave(options = {})
14
+ Wave.new(
15
+ options[:id] || "id#{sequence}@wave.google.com",
16
+ options
17
+ )
18
+ end
19
+
20
+ def wavelet(options = {})
21
+ Wave::Wavelet.new(
22
+ { :wave => options[:wave] || Factory.wave
23
+ }.merge(options)
24
+ )
25
+ end
26
+
27
+ def participant(options = {})
28
+ Wave::Participant.new(
29
+ { :id => "id#{sequence}@email.com",
30
+ :wavelet => options[:wavelet] || Factory.wavelet
31
+ }.merge(options)
32
+ )
33
+ end
34
+
35
+ def blip(options = {})
36
+ wavelet = options[:wavelet] || Factory.wavelet
37
+ Wave::Blip.new(
38
+ { :wavelet => wavelet,
39
+ :creator => Factory.participant(:wavelet => wavelet)
40
+ }.merge(options)
41
+ )
42
+ end
43
+
44
+ def document(options = {})
45
+ Wave::Document.new(
46
+ 'IMAGE',
47
+ { :wavelet => wavelet,
48
+ :blip => Factory.blip,
49
+ :creator => Factory.participant(:wavelet => wavelet)
50
+ }.merge(options)
51
+ )
52
+ end
53
+
54
+ def annotation(options = {})
55
+ Wave::Annotation.new(
56
+ options[:document] || Factory.document,
57
+ options[:name] || "Annotation#{sequence}",
58
+ options[:value] || "content number #{sequence}",
59
+ options[:range] || 4..11
60
+ )
61
+ end
62
+
63
+ protected
64
+ def sequence
65
+ @sequence ||= 0
66
+ @sequence += 1
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class WaveTest < Test::Unit::TestCase
4
+
5
+ context "instantiating a wave" do
6
+ context "without any id" do
7
+ should "raise an error" do
8
+ assert_raises(ArgumentError) { @wave = Wave.new }
9
+ end
10
+ end
11
+ should "set the wave id" do
12
+ assert Factory.wave.id =~
13
+ /^[\w\d]+@[\w\d]+\.[\w\d]+/
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class WaveletTest < Test::Unit::TestCase
4
+
5
+ context "a wavelet" do
6
+ setup { @wavelet = Factory.wavelet }
7
+ should "have a wave" do
8
+ assert @wavelet.wave
9
+ end
10
+ should "require a wave" do
11
+ assert_raises Wave::WaveError do
12
+ Wave::Wavelet.new
13
+ end
14
+ end
15
+ should "have a participant list" do
16
+ assert @wavelet.participants
17
+ end
18
+ should "have a collection of blips" do
19
+ assert @wavelet.blips
20
+ end
21
+ should "register itself in it's wave's wavelet collection" do
22
+ assert @wavelet.wave.wavelets.include?(@wavelet)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,63 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{wave}
5
+ s.version = "0.0.4"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jack Danger Canty"]
9
+ s.date = %q{2009-05-30}
10
+ s.email = %q{google-wave@jackcanty.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.markdown"
14
+ ]
15
+ s.files = [
16
+ "LICENSE",
17
+ "README.markdown",
18
+ "Rakefile",
19
+ "VERSION",
20
+ "lib/wave.rb",
21
+ "lib/wave/annotation.rb",
22
+ "lib/wave/blip.rb",
23
+ "lib/wave/document.rb",
24
+ "lib/wave/events.rb",
25
+ "lib/wave/participant.rb",
26
+ "lib/wave/robot.rb",
27
+ "lib/wave/wavelet.rb",
28
+ "test/annotation_test.rb",
29
+ "test/blip_test.rb",
30
+ "test/document_test.rb",
31
+ "test/participant_test.rb",
32
+ "test/robot_test.rb",
33
+ "test/test_helper.rb",
34
+ "test/wave_test.rb",
35
+ "test/wavelet_test.rb",
36
+ "wave.gemspec"
37
+ ]
38
+ s.homepage = %q{http://github.com/JackDanger/wave}
39
+ s.rdoc_options = ["--charset=UTF-8"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.3.3}
42
+ s.summary = %q{Ruby client for the Google Wave Federation Protocol}
43
+ s.test_files = [
44
+ "test/annotation_test.rb",
45
+ "test/blip_test.rb",
46
+ "test/document_test.rb",
47
+ "test/participant_test.rb",
48
+ "test/robot_test.rb",
49
+ "test/test_helper.rb",
50
+ "test/wave_test.rb",
51
+ "test/wavelet_test.rb"
52
+ ]
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
59
+ else
60
+ end
61
+ else
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: JackDanger-wave
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Jack Danger Canty
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-30 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: google-wave@jackcanty.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.markdown
25
+ files:
26
+ - LICENSE
27
+ - README.markdown
28
+ - Rakefile
29
+ - VERSION
30
+ - lib/wave.rb
31
+ - lib/wave/annotation.rb
32
+ - lib/wave/blip.rb
33
+ - lib/wave/document.rb
34
+ - lib/wave/events.rb
35
+ - lib/wave/participant.rb
36
+ - lib/wave/robot.rb
37
+ - lib/wave/wavelet.rb
38
+ - test/annotation_test.rb
39
+ - test/blip_test.rb
40
+ - test/document_test.rb
41
+ - test/participant_test.rb
42
+ - test/robot_test.rb
43
+ - test/test_helper.rb
44
+ - test/wave_test.rb
45
+ - test/wavelet_test.rb
46
+ - wave.gemspec
47
+ has_rdoc: false
48
+ homepage: http://github.com/JackDanger/wave
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.2.0
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Ruby client for the Google Wave Federation Protocol
73
+ test_files:
74
+ - test/annotation_test.rb
75
+ - test/blip_test.rb
76
+ - test/document_test.rb
77
+ - test/participant_test.rb
78
+ - test/robot_test.rb
79
+ - test/test_helper.rb
80
+ - test/wave_test.rb
81
+ - test/wavelet_test.rb