erkki-bitly 0.3.1

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.
@@ -0,0 +1,48 @@
1
+ === 0.3 / 2009-07-09
2
+
3
+ * 1 major enhancement
4
+
5
+ * a full set of tests, properly mocked
6
+
7
+ * 1 minor enhancement
8
+
9
+ * calling bitly.shorten(:history => 1) will add the url to the api user's history.
10
+
11
+ * 1 bug fix
12
+
13
+ * you can no longer call shorten with a keyword, this was unsupported in the API and consequently removed
14
+
15
+ === 0.2 / 2009-06-23
16
+
17
+ * 1 enhancement
18
+
19
+ * Depends on Crack instead of JSON, so can run on Jruby
20
+
21
+ * 1 bug fix
22
+
23
+ * Does not choke when bit.ly chokes. Returns a BitlyError instead
24
+
25
+ === 0.1.4 / 2009-04-13
26
+
27
+ * 1 bug fix
28
+
29
+ * Urls with parameters were choking, changed to using CGI.
30
+
31
+ === 0.1.2 / 2009-03-12
32
+
33
+ * 1 minor enhancement
34
+
35
+ * Allows to add a keyword for shortening urls
36
+
37
+ === 0.1.1 / 2009-01-26
38
+
39
+ * 1 bug fix
40
+
41
+ * Didn't include dependency on JSON
42
+
43
+ === 0.1.0 / 2009-01-26
44
+
45
+ * 1 major enhancement
46
+
47
+ * First release
48
+
@@ -0,0 +1,11 @@
1
+ bitly.gemspec
2
+ History.txt
3
+ lib/bitly/client.rb
4
+ lib/bitly/url.rb
5
+ lib/bitly/utils.rb
6
+ lib/bitly/version.rb
7
+ lib/bitly.rb
8
+ Manifest
9
+ Rakefile
10
+ README.txt
11
+ test/test_bitly.rb
@@ -0,0 +1,65 @@
1
+ = bitly
2
+
3
+ == DESCRIPTION:
4
+
5
+ A Ruby API for bit.ly
6
+
7
+ http://code.google.com/p/bitly-api/wiki/ApiDocumentation
8
+
9
+ == INSTALLATION:
10
+
11
+ gem install bitly
12
+
13
+ == USAGE:
14
+
15
+ Create a Bitly client using your username and api key as follows:
16
+
17
+ bitly = Bitly.new(username, api_key)
18
+
19
+ You can then use that client to shorten or expand urls or return more information or statistics as so:
20
+
21
+ bitly.shorten('http://www.google.com')
22
+ bitly.shorten('http://www.google.com', :history => 1) # adds the url to the api user's history
23
+ bitly.expand('wQaT')
24
+ bitly.info('http://bit.ly/wQaT')
25
+ bitly.stats('http://bit.ly/wQaT')
26
+
27
+ Each can be used in all the methods described in the API docs, the shorten function, for example, takes a url or an array of urls.
28
+
29
+ All four functions return a Bitly::Url object (or an array of Bitly::Url objects if you supplied an array as the input). You can then get all the information required from that object.
30
+
31
+ u = bitly.shorten('http://www.google.com') #=> Bitly::Url
32
+
33
+ u.long_url #=> "http://www.google.com"
34
+ u.short_url #=> "http://bit.ly/Ywd1"
35
+ u.user_hash #=> "Ywd1"
36
+ u.hash #=> "2V6CFi"
37
+ u.info #=> a ruby hash of the JSON returned from the API
38
+ u.stats #=> a ruby hash of the JSON returned from the API
39
+
40
+ bitly.shorten('http://www.google.com', 'keyword')
41
+
42
+ == LICENSE:
43
+
44
+ (The MIT License)
45
+
46
+ Copyright (c) 2009 Phil Nash
47
+
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of this software and associated documentation files (the
50
+ 'Software'), to deal in the Software without restriction, including
51
+ without limitation the rights to use, copy, modify, merge, publish,
52
+ distribute, sublicense, and/or sell copies of the Software, and to
53
+ permit persons to whom the Software is furnished to do so, subject to
54
+ the following conditions:
55
+
56
+ The above copyright notice and this permission notice shall be
57
+ included in all copies or substantial portions of the Software.
58
+
59
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
60
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
62
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
63
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
64
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
65
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'echoe'
6
+ require './lib/bitly.rb'
7
+
8
+ # modified by coryosborn to remove native JSON dependency
9
+
10
+ Echoe.new('bitly', Bitly::VERSION) do |p|
11
+ p.description = "Use the bit.ly API to shorten or expand URLs"
12
+ p.url = "http://github.com/philnash/bitly"
13
+ p.author = "Phil Nash"
14
+ p.email = "philnash@gmail.com"
15
+ p.extra_deps = [['crack', '>= 0.1.1']]
16
+ p.development_dependencies = []
17
+ end
18
+
19
+ # vim: syntax=Ruby
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bitly}
5
+ s.version = "0.3.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Phil Nash"]
9
+ s.date = %q{2009-07-09}
10
+ s.description = %q{Use the bit.ly API to shorten or expand URLs}
11
+ s.email = %q{philnash@gmail.com}
12
+ s.extra_rdoc_files = ["lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/version.rb", "lib/bitly.rb", "README.txt"]
13
+ s.files = ["bitly.gemspec", "History.txt", "lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/version.rb", "lib/bitly.rb", "Manifest", "Rakefile", "README.txt", "test/test_bitly.rb", "test/bitly/test_client.rb", "test/bitly/test_url.rb", "test/bitly/test_utils.rb", "test/test_helper.rb"]
14
+ s.homepage = %q{http://github.com/philnash/bitly}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bitly", "--main", "README.txt"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{bitly}
18
+ s.rubygems_version = %q{1.3.4}
19
+ s.summary = %q{Use the bit.ly API to shorten or expand URLs}
20
+ s.test_files = ["test/bitly/test_client.rb", "test/bitly/test_url.rb", "test/bitly/test_utils.rb", "test/test_bitly.rb", "test/test_helper.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
28
+ else
29
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ gem 'crack'
5
+ require 'crack'
6
+
7
+ require 'bitly/utils'
8
+ require 'bitly/client'
9
+ require 'bitly/url'
10
+ require 'bitly/version'
@@ -0,0 +1,150 @@
1
+ require 'rubygems'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ module Bitly
6
+ API_URL = 'http://api.bit.ly/'
7
+ API_VERSION = '2.0.1'
8
+
9
+ def self.new(login, api_key)
10
+ Bitly::Client.new(login,api_key)
11
+ end
12
+
13
+ class Client
14
+
15
+ include Bitly::Utils
16
+
17
+ def initialize(login,api_key)
18
+ @login = login
19
+ @api_key = api_key
20
+ end
21
+
22
+ def shorten(input, opts={})
23
+ if input.is_a? String
24
+ request = create_url("shorten", :longUrl => input, :history => (opts[:history] ? 1 : nil))
25
+ result = get_result(request)
26
+ result = {:long_url => input}.merge result[input]
27
+ Bitly::Url.new(@login,@api_key,result)
28
+ elsif input.is_a? Array
29
+ request = create_url("shorten", :history => (opts[:history] ? 1 : nil))
30
+ request.query << "&" + input.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless input.nil?
31
+ result = get_result(request)
32
+ input.map do |long_url|
33
+ new_url = {:long_url => long_url}.merge result[long_url]
34
+ long_url = Bitly::Url.new(@login,@api_key,new_url)
35
+ end
36
+ else
37
+ raise ArgumentError.new("Shorten requires either a url or an array of urls")
38
+ end
39
+ end
40
+
41
+ def expand(input)
42
+ if input.is_a? String
43
+ if input.include? "bit.ly/"
44
+ hash = create_hash_from_url(input)
45
+ request = create_url "expand", :hash => hash
46
+ result = get_result(request)
47
+ result = { :short_url => input, :hash => hash }.merge result[hash]
48
+ else
49
+ request = create_url "expand", :hash => input
50
+ result = get_result(request)
51
+ result = { :hash => input, :short_url => "http://bit.ly/#{input}" }.merge result[input]
52
+ end
53
+ Bitly::Url.new(@login,@api_key,result)
54
+ elsif input.is_a? Array
55
+ request = create_url "expand", :hash => input.join(',')
56
+ result = get_result(request)
57
+ input.map do |hsh|
58
+ new_url = {:hash => hsh, :short_url => "http://bit.ly/#{hsh}"}.merge result[hsh]
59
+ hsh = Bitly::Url.new(@login,@api_key,new_url)
60
+ end
61
+ else
62
+ raise ArgumentError('Expand requires either a short url, a hash or an array of hashes')
63
+ end
64
+ end
65
+
66
+ def info(input)
67
+ if input.is_a? String
68
+ if input.include? "bit.ly/"
69
+ hash = create_hash_from_url(input)
70
+ request = create_url 'info', :hash => hash
71
+ result = get_result(request)
72
+ result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result[hash]
73
+ else
74
+ request = create_url 'info', :hash => input
75
+ result = get_result(request)
76
+ result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result[input]
77
+ end
78
+ Bitly::Url.new(@login,@api_key,result)
79
+ elsif input.is_a? Array
80
+ request = create_url "info", :hash => input.join(',')
81
+ result = get_result(request)
82
+ input.map do |hsh|
83
+ new_url = {:hash => hsh, :short_url => "http://bit.ly/#{hsh}"}.merge result[hsh]
84
+ hsh = Bitly::Url.new(@login,@api_key,:info => new_url)
85
+ end
86
+ else
87
+ raise ArgumentError.new('Info requires either a short url, a hash or an array of hashes')
88
+ end
89
+ end
90
+
91
+ def stats(input)
92
+ if input.is_a? String
93
+ if input.include? "bit.ly/"
94
+ hash = create_hash_from_url(input)
95
+ request = create_url 'stats', :hash => hash
96
+ result = get_result(request)
97
+ result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result
98
+ else
99
+ request = create_url 'stats', :hash => input
100
+ result = get_result(request)
101
+ result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result
102
+ end
103
+ Bitly::Url.new(@login,@api_key,:stats => result)
104
+ else
105
+ raise ArgumentError.new("Stats requires either a short url or a hash")
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+ class BitlyError < StandardError
114
+ attr_reader :code
115
+ alias :msg :message
116
+ def initialize(msg, code)
117
+ @code = code
118
+ super("#{msg} - '#{code}'")
119
+ end
120
+ end
121
+
122
+
123
+ # How it should work
124
+ # ==================
125
+ # bitly = Bitly::Base.new('philnash','R_7776acc394294b2b0ad2c261a91c483d')
126
+ # bitly.shorten("http://www.google.com")
127
+ # #=> Bitly::Url
128
+ # bitly.shorten(["http://www.google.com","http://cnn.com"])
129
+ # #=> [Bitly::Url,Bitly::Url]
130
+ #
131
+ # bitly.expand("http://bit.ly/wIRm")
132
+ # #=> Bitly::Url
133
+ # bitly.expand("wIRm")
134
+ # #=> Bitly::Url
135
+ # bitly.expand(["wIRm","sdfsd"])
136
+ # #=> [Bitly::Url,Bitly::Url]
137
+ #
138
+ # bitly.info("http://bit.ly/wIRm") || bitly.info("wIRm")
139
+ # #=> b = Bitly::Url
140
+ # #=> b.info #=> hash of data back from info
141
+ # bitly.info(['wIRm','qsads'])
142
+ # #=> [Bitly::Url, Bitly::Url]
143
+ # also, with any url = Bitly::Url
144
+ # url.info #=> hash of info data
145
+
146
+ # bitly.stats("http://bit.ly/wIRm") || bitly.stats("wIRm")
147
+ # #=> b = Bitly::Url
148
+ # #=> b.stats #=> hash of stats
149
+ # also, any url = Bitly::Url
150
+ # url.stats #=> hash of stats
@@ -0,0 +1,97 @@
1
+ module Bitly
2
+
3
+ class Url
4
+ include Bitly::Utils
5
+
6
+ attr_accessor :long_url, :short_url, :hash, :user_hash
7
+ attr_reader :info, :stats
8
+ VARIABLES = ['long_url', 'short_url', 'hash', 'user_hash']
9
+
10
+ def initialize(login,api_key,obj=nil)
11
+ unless obj.nil?
12
+ raise BitlyError.new(result['errorMessage'],result['errorCode']) if obj['statusCode'] == "ERROR"
13
+ instance_variablise(obj, VARIABLES)
14
+ @info = obj[:info] if obj[:info]
15
+ @stats = obj[:stats] if obj[:stats]
16
+ end
17
+ @login = login
18
+ @api_key = api_key
19
+ raise ArgumentError.new("Please provide a login and api_key") if @login.nil? || @api_key.nil?
20
+ end
21
+
22
+ def shorten(opts = {})
23
+ return @short_url if @short_url
24
+ unless @long_url.nil?
25
+ request = create_url("shorten", :longUrl => @long_url, :history => (opts[:history] ? 1 : nil))
26
+ result = get_result(request)[@long_url.gsub(/\/$/,'')]
27
+ if result['statusCode'] == "ERROR"
28
+ raise BitlyError.new(result['errorMessage'],result['errorCode'])
29
+ else
30
+ instance_variablise(result,VARIABLES)
31
+ return @short_url
32
+ end
33
+ else
34
+ raise ArgumentError.new("You need a long_url in order to shorten it")
35
+ end
36
+ end
37
+
38
+ def expand
39
+ return @long_url if @long_url
40
+ unless !(@short_url || @hash)
41
+ unless @hash
42
+ @hash = create_hash_from_url(@short_url)
43
+ end
44
+ request = create_url("expand", :hash => @hash)
45
+ result = get_result(request)[@hash]
46
+ if result['statusCode'] == "ERROR"
47
+ raise BitlyError.new(result['errorMessage'],result['errorCode'])
48
+ else
49
+ instance_variablise(result,VARIABLES)
50
+ return @long_url
51
+ end
52
+ else
53
+ raise ArgumentError.new("You need a short_url or a hash in order to expand it")
54
+ end
55
+ end
56
+
57
+ def info
58
+ if @info.nil?
59
+ if @hash
60
+ request = create_url "info", :hash => @hash
61
+ result = get_result(request)[@hash]
62
+ instance_variablise(result, VARIABLES)
63
+ @info = result
64
+ elsif @short_url
65
+ @hash = create_hash_from_url(@short_url)
66
+ request = create_url "info", :hash => hash
67
+ result = get_result(request)[hash]
68
+ instance_variablise(result, VARIABLES)
69
+ @info = result
70
+ else
71
+ raise ArgumentError.new("You need a hash or short_url in order to get info")
72
+ end
73
+ return @info
74
+ else
75
+ @info
76
+ end
77
+ end
78
+
79
+ def stats
80
+ if @stats.nil?
81
+ if @hash
82
+ request = create_url "stats", :hash => @hash
83
+ elsif @short_url
84
+ @hash = create_hash_from_url(@short_url)
85
+ request = create_url "stats", :hash => @hash
86
+ else
87
+ raise ArgumentError.new("You need a hash or short_url in order to get stats")
88
+ end
89
+ @stats = get_result(request)
90
+ else
91
+ @stats
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,58 @@
1
+ require 'cgi'
2
+
3
+ module Bitly
4
+ module Utils
5
+ def underscore(camel_cased_word) # stolen from rails
6
+ camel_cased_word.to_s.gsub(/::/, '/').
7
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
8
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
9
+ tr("-", "_").
10
+ downcase
11
+ end
12
+
13
+ def create_hash_from_url(url)
14
+ url.gsub(/^.*bit.ly\//,'')
15
+ end
16
+
17
+ def attr_define(k,v)
18
+ instance_variable_set("@#{k}", v)
19
+ meta = class << self; self; end
20
+ meta.class_eval { attr_reader k.to_sym }
21
+ end
22
+
23
+ def instance_variablise(obj,variables)
24
+ if obj.is_a? Hash
25
+ obj.each do |k,v|
26
+ if v.is_a? Hash
27
+ instance_variablise(v,variables)
28
+ else
29
+ attr_define(underscore(k),v) if variables.include?(underscore(k))
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def create_url(resource="",args={})
36
+ args = args.merge({:login => @login, :apiKey => @api_key, :version => API_VERSION})
37
+ url = URI.join(API_URL,resource)
38
+ long_urls = args.delete(:long_urls)
39
+ url.query = args.map { |k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
40
+ url.query << "&" + long_urls.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless long_urls.nil?
41
+ url
42
+ end
43
+
44
+ def get_result(request)
45
+ begin
46
+ result = Crack::JSON.parse(Net::HTTP.get(request))
47
+ rescue
48
+ result = {'errorMessage' => 'JSON Parse Error(Bit.ly messed up)', 'errorCode' => 69, 'statusCode' => 'ERROR'}
49
+ end
50
+ if result['statusCode'] == "OK"
51
+ result = result['results']
52
+ else
53
+ raise BitlyError.new(result['errorMessage'],result['errorCode'])
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module Bitly
2
+ VERSION = '0.3'
3
+ end
@@ -0,0 +1,187 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper.rb')
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+ context "bitly module" do
5
+ should "create a new bitly client" do
6
+ b = Bitly.new(login, api_key)
7
+ assert_equal Bitly::Client, b.class
8
+ end
9
+ end
10
+ context "using the bitly client" do
11
+ setup do
12
+ @bitly = Bitly.new(login, api_key)
13
+ end
14
+
15
+ context "shortening" do
16
+ context "a single link" do
17
+ setup do
18
+ stub_get(/^http:\/\/api.bit.ly\/shorten\?.*longUrl=.*cnn.com.*$/,"cnn.json")
19
+ @url = @bitly.shorten('http://cnn.com')
20
+ end
21
+ should "return a Bitly::Url" do
22
+ assert_kind_of Bitly::Url, @url
23
+ end
24
+ should "return a short bitly url" do
25
+ assert_equal "http://bit.ly/15DlK", @url.short_url
26
+ end
27
+ should "save the long url" do
28
+ assert_equal "http://cnn.com", @url.long_url
29
+ end
30
+ end
31
+ context "multiple links" do
32
+ setup do
33
+ stub_get(/^http:\/\/api.bit.ly\/shorten\?.*longUrl=.*longUrl=.*$/,"cnn_and_google.json")
34
+ @urls = @bitly.shorten(['http://cnn.com', 'http://google.com'])
35
+ end
36
+ should "return an array of Bitly::Urls" do
37
+ assert_kind_of Array, @urls
38
+ assert_kind_of Bitly::Url, @urls[0]
39
+ end
40
+ should "shorten the urls in order" do
41
+ assert_equal "http://bit.ly/15DlK", @urls[0].short_url
42
+ assert_equal "http://bit.ly/11etr", @urls[1].short_url
43
+ end
44
+ should "save the long urls" do
45
+ assert_equal "http://cnn.com", @urls[0].long_url
46
+ assert_equal "http://google.com", @urls[1].long_url
47
+ end
48
+ end
49
+ context "no links" do
50
+ should "raise an ArgumentError" do
51
+ assert_raise ArgumentError do
52
+ @bitly.shorten
53
+ end
54
+ end
55
+ end
56
+ end
57
+ context "expanding" do
58
+ context "a hash" do
59
+ setup do
60
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
61
+ @url = @bitly.expand("31IqMl")
62
+ end
63
+ should "return a Bitly::Url" do
64
+ assert_kind_of Bitly::Url, @url
65
+ end
66
+ should "return the expanded url" do
67
+ assert_equal "http://cnn.com/", @url.long_url
68
+ end
69
+ should "save the hash" do
70
+ assert_equal "31IqMl", @url.hash
71
+ end
72
+ should "save the short url" do
73
+ assert_equal "http://bit.ly/31IqMl", @url.short_url
74
+ end
75
+ end
76
+ context "a short url" do
77
+ setup do
78
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
79
+ @url = @bitly.expand("http://bit.ly/31IqMl")
80
+ end
81
+ should "return a Bitly::Url" do
82
+ assert_kind_of Bitly::Url, @url
83
+ end
84
+ should "return the expanded url" do
85
+ assert_equal "http://cnn.com/", @url.long_url
86
+ end
87
+ should "save the hash" do
88
+ assert_equal "31IqMl", @url.hash
89
+ end
90
+ should "save the short url" do
91
+ assert_equal "http://bit.ly/31IqMl", @url.short_url
92
+ end
93
+ end
94
+ context "multiple hashes" do
95
+ setup do
96
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=15DlK.*3j4ir4.*$/,"expand_cnn_and_google.json")
97
+ @urls = @bitly.expand(["15DlK","3j4ir4"])
98
+ end
99
+ should "return an array of Bitly::Urls" do
100
+ assert_kind_of Array, @urls
101
+ assert_kind_of Bitly::Url, @urls[0]
102
+ assert_kind_of Bitly::Url, @urls[1]
103
+ end
104
+ should "expand the hashes in order" do
105
+ assert_equal "http://cnn.com/", @urls[0].long_url
106
+ assert_equal "http://google.com/", @urls[1].long_url
107
+ end
108
+ should "save the hash to each url" do
109
+ assert_equal "15DlK", @urls[0].hash
110
+ assert_equal "3j4ir4", @urls[1].hash
111
+ end
112
+ end
113
+ end
114
+ context "to get info on" do
115
+ context "a single link" do
116
+ setup do
117
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
118
+ @url = @bitly.info('http://bit.ly/3j4ir4')
119
+ end
120
+ should "return a Bitly::Url" do
121
+ assert_kind_of Bitly::Url, @url
122
+ end
123
+ should "return an info object with the url" do
124
+ assert_not_nil @url.info
125
+ end
126
+ end
127
+ context "a single hash" do
128
+ setup do
129
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
130
+ @url = @bitly.info('3j4ir4')
131
+ end
132
+ should "return a Bitly::Url" do
133
+ assert_kind_of Bitly::Url, @url
134
+ end
135
+ should "return an info object with the url" do
136
+ assert_not_nil @url.info
137
+ end
138
+ end
139
+ context "a list of hashes" do
140
+ setup do
141
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*31IqMl.*$/,"google_and_cnn_info.json")
142
+ @urls = @bitly.info(['3j4ir4','31IqMl'])
143
+ end
144
+ should "return a Bitly::Url" do
145
+ assert_kind_of Array, @urls
146
+ end
147
+ should "return an info object with the url" do
148
+ assert_not_nil @urls[0].info
149
+ assert_not_nil @urls[1].info
150
+ end
151
+ end
152
+ end
153
+ context "to get stats on" do
154
+ context "a single link" do
155
+ setup do
156
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
157
+ @url = @bitly.stats('http://bit.ly/3j4ir4')
158
+ end
159
+ should "return a Bitly::Url" do
160
+ assert_kind_of Bitly::Url, @url
161
+ end
162
+ should "return an stats object" do
163
+ assert_not_nil @url.stats
164
+ end
165
+ end
166
+ context "a single hash" do
167
+ setup do
168
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
169
+ @url = @bitly.stats('3j4ir4')
170
+ end
171
+ should "return a Bitly::Url" do
172
+ assert_kind_of Bitly::Url, @url
173
+ end
174
+ should "return an stats object" do
175
+ assert_not_nil @url.stats
176
+ end
177
+ end
178
+ context "a list of hashes" do
179
+ should "return an argument error" do
180
+ assert_raise ArgumentError do
181
+ @bitly.stats(['3j4ir4','31IqMl'])
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,168 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper.rb')
2
+
3
+ class TestUrl < Test::Unit::TestCase
4
+ context "a new Bitly::Url" do
5
+ should "require a login and api_key" do
6
+ assert_raise ArgumentError do Bitly::Url.new end
7
+ assert_raise ArgumentError do Bitly::Url.new(login) end
8
+ assert_raise ArgumentError do Bitly::Url.new(nil, api_key) end
9
+ assert_nothing_raised do
10
+ Bitly::Url.new(login, api_key)
11
+ Bitly::Url.new(login, api_key, :hash => '3j4ir4')
12
+ Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
13
+ Bitly::Url.new(login, api_key, :long_url => 'http://google.com/')
14
+ end
15
+ end
16
+ context "shortening" do
17
+ context "with a long url" do
18
+ setup do
19
+ stub_get(/^http:\/\/api.bit.ly\/shorten\?.*longUrl=.*cnn.com.*$/,"cnn.json")
20
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://cnn.com/')
21
+ end
22
+ should "return a short url" do
23
+ assert_equal "http://bit.ly/15DlK", @url.shorten
24
+ end
25
+ end
26
+ context "with no long url" do
27
+ setup do
28
+ @url = Bitly::Url.new(login, api_key)
29
+ end
30
+ should "raise an error" do
31
+ assert_raise ArgumentError do
32
+ @url.shorten
33
+ end
34
+ end
35
+ end
36
+ context "with a short url already" do
37
+ setup do
38
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/31IqMl')
39
+ flexmock(@url).should_receive(:create_url).never
40
+ end
41
+ should "not need to call the api" do
42
+ assert_equal "http://bit.ly/31IqMl", @url.shorten
43
+ end
44
+ end
45
+ end
46
+ context "expanding" do
47
+ context "with a hash" do
48
+ setup do
49
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
50
+ @url = Bitly::Url.new(login, api_key, :hash => '31IqMl')
51
+ end
52
+ should "return an expanded url" do
53
+ assert_equal "http://cnn.com/", @url.expand
54
+ end
55
+ end
56
+ context "with a short url" do
57
+ setup do
58
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
59
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/31IqMl')
60
+ end
61
+ should "return an expanded url" do
62
+ assert_equal "http://cnn.com/", @url.expand
63
+ end
64
+ end
65
+ context "with no short url or hash" do
66
+ setup do
67
+ @url = Bitly::Url.new(login, api_key)
68
+ end
69
+ should "raise an error" do
70
+ assert_raise ArgumentError do
71
+ @url.expand
72
+ end
73
+ end
74
+ end
75
+ context "with a long url already" do
76
+ setup do
77
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://google.com')
78
+ flexmock(@url).should_receive(:create_url).never
79
+ end
80
+ should "not need to call the api" do
81
+ assert_equal "http://google.com", @url.expand
82
+ end
83
+ end
84
+ end
85
+ context "info" do
86
+ context "with a hash" do
87
+ setup do
88
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
89
+ @url = Bitly::Url.new(login, api_key, :hash => '3j4ir4')
90
+ end
91
+ should "return info" do
92
+ assert_equal "Google", @url.info['htmlTitle']
93
+ end
94
+ end
95
+ context "with a short url" do
96
+ setup do
97
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
98
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
99
+ end
100
+ should "return an expanded url" do
101
+ assert_equal "Google", @url.info['htmlTitle']
102
+ end
103
+ end
104
+ context "without a short url or hash" do
105
+ setup do
106
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://google.com')
107
+ end
108
+ should "raise an error" do
109
+ assert_raise ArgumentError do
110
+ @url.info
111
+ end
112
+ end
113
+ end
114
+ context "with info already" do
115
+ setup do
116
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
117
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
118
+ @url.info
119
+ end
120
+ should "not call the api twice" do
121
+ flexmock(@url).should_receive(:create_url).never
122
+ @url.info
123
+ end
124
+ end
125
+ end
126
+ context "stats" do
127
+ context "with a hash" do
128
+ setup do
129
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
130
+ @url = Bitly::Url.new(login, api_key, :hash => '3j4ir4')
131
+ end
132
+ should "return info" do
133
+ assert_equal 2644, @url.stats['clicks']
134
+ end
135
+ end
136
+ context "with a short url" do
137
+ setup do
138
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
139
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
140
+ end
141
+ should "return an expanded url" do
142
+ assert_equal 2644, @url.stats['clicks']
143
+ end
144
+ end
145
+ context "without a short url or hash" do
146
+ setup do
147
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://google.com')
148
+ end
149
+ should "raise an error" do
150
+ assert_raise ArgumentError do
151
+ @url.stats
152
+ end
153
+ end
154
+ end
155
+ context "with info already" do
156
+ setup do
157
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
158
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
159
+ @url.stats
160
+ end
161
+ should "not call the api twice" do
162
+ flexmock(@url).should_receive(:create_url).never
163
+ @url.stats
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,76 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper.rb')
2
+
3
+ class TestUtils < Test::Unit::TestCase
4
+ include Bitly::Utils
5
+ API_VERSION = '2.0.1'
6
+
7
+ context "text utils" do
8
+ should "underscore a word" do
9
+ assert_equal "hello_world", underscore("HelloWorld")
10
+ end
11
+ should "create a hash from a short url" do
12
+ assert_equal "hello", create_hash_from_url("http://bit.ly/hello")
13
+ end
14
+ end
15
+
16
+ context "class utils" do
17
+ should "turn a key value pair into an instance variable" do
18
+ attr_define('hello','goodbye')
19
+ assert_equal @hello, "goodbye"
20
+ end
21
+
22
+ should "turn a hash into instance variables" do
23
+ instance_variablise({'hello' => 'goodbye'}, ['hello'])
24
+ assert_equal @hello, "goodbye"
25
+ end
26
+
27
+ should "not turn nonspecified variables into instance variables" do
28
+ instance_variablise({'hello' => 'goodbye'}, [])
29
+ assert_nil @hello
30
+ end
31
+ end
32
+
33
+ context "creating a url" do
34
+ setup do
35
+ @api_key = api_key
36
+ @login = login
37
+ end
38
+ should "contain all the basic information" do
39
+ url = create_url.to_s
40
+ assert url.include?('http://api.bit.ly/')
41
+ assert url.include?("version=#{API_VERSION}")
42
+ assert url.include?("apiKey=#{api_key}")
43
+ assert url.include?("login=#{login}")
44
+ end
45
+ should "contain the right resource" do
46
+ url = create_url('shorten').to_s
47
+ assert url.include?('/shorten')
48
+ end
49
+ should "contain extra parameters" do
50
+ url = create_url('shorten', :longUrl => 'http://google.com').to_s
51
+ assert url.include?("longUrl=#{CGI.escape('http://google.com')}")
52
+ end
53
+ end
54
+
55
+ context "fetching a url" do
56
+ context "successfully" do
57
+ setup do
58
+ stub_get("http://example.com","cnn.json")
59
+ end
60
+ should "return a json object successfully" do
61
+ result = get_result(URI.join("http://example.com"))
62
+ assert_equal Hash, result.class
63
+ end
64
+ end
65
+ context "unsuccessfully" do
66
+ setup do
67
+ stub_get("http://example.com", 'shorten_error.json')
68
+ end
69
+ should "raise BitlyError" do
70
+ assert_raise BitlyError do
71
+ result = get_result(URI.join("http://example.com"))
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,81 @@
1
+ # require 'test/unit'
2
+ # require 'rubygems'
3
+ # require 'shoulda'
4
+ # require 'flexmock'
5
+ # require 'bitly'
6
+ #
7
+ # class TestBitly < Test::Unit::TestCase
8
+ #
9
+ # context "with a bitly client" do
10
+ # setup do
11
+ # @api_key = 'test_key'
12
+ # @login = 'test_account'
13
+ # @bitly = Bitly.new(@login,@api_key)
14
+ # end
15
+ #
16
+ # context "shortening" do
17
+ #
18
+ # context "a single url" do
19
+ # setup do
20
+ #
21
+ # end
22
+ # def test_returns_single_short_url
23
+ # url = @bitly.shorten("http://cnn.com")
24
+ # assert_kind_of Bitly::Url, url
25
+ # assert_equal "http://cnn.com", url.long_url
26
+ # assert_equal "http://bit.ly/15DlK", url.short_url
27
+ # end
28
+ #
29
+ # def test_shortens_multiple_urls
30
+ # urls = @bitly.shorten(["http://cnn.com","http://google.com"])
31
+ # assert_equal "http://cnn.com", urls[0].long_url
32
+ # assert_equal "http://bit.ly/15DlK", urls[0].short_url
33
+ # assert_equal "http://google.com", urls[1].long_url
34
+ # assert_equal "http://bit.ly/11etr", urls[1].short_url
35
+ # end
36
+ #
37
+ # def test_can_shorten_a_url_with_parameters
38
+ # url = @bitly.shorten("http://www.google.com/search?hl=en&q=url&btnG=Google+Search&aq=f&oq=")
39
+ # assert_kind_of Bitly::Url, url
40
+ # assert_equal "http://www.google.com/search?hl=en&q=url&btnG=Google+Search&aq=f&oq=", url.long_url
41
+ # assert_equal "http://bit.ly/NqK6i", url.short_url
42
+ # end
43
+ #
44
+ # def test_returns_a_long_url
45
+ # urls = @bitly.expand(["2bYgqR","1RmnUT"])
46
+ # assert_kind_of Bitly::Url, urls[0]
47
+ # assert_equal "http://cnn.com", urls[0].long_url
48
+ # assert_equal "2bYgqR", urls[0].hash
49
+ # assert_equal "http://google.com", urls[1].long_url
50
+ # assert_equal "1RmnUT", urls[1].hash
51
+ # url = @bitly.expand("http://bit.ly/wQaT")
52
+ # assert_kind_of Bitly::Url, url
53
+ # assert_equal "http://bit.ly/wQaT", url.short_url
54
+ # assert_equal "http://google.com/", url.long_url
55
+ # assert_equal "wQaT", url.hash
56
+ # url2 = @bitly.expand("wQaT")
57
+ # assert_kind_of Bitly::Url, url2
58
+ # assert_equal "wQaT", url2.hash
59
+ # assert_equal "http://bit.ly/wQaT", url2.short_url
60
+ # assert_equal "http://google.com/", url2.long_url
61
+ # end
62
+ #
63
+ # # def test_returns_keyword_url
64
+ # # #kind of ghetto test but we need it to be different every time
65
+ # # require 'digest/sha1'
66
+ # # keyword = Digest::SHA1.hexdigest(DateTime.now.to_s)
67
+ # #
68
+ # # url = @bitly.shorten("http://google.com", :keyword => keyword)
69
+ # # assert_equal url.short_keyword_url, "http://bit.ly/#{keyword}"
70
+ # # end
71
+ #
72
+ # def test_returns_error_on_existing_keyword
73
+ # keyword = 'apple'
74
+ # assert_raise BitlyError do
75
+ # @bitly.shorten("http://apple.com/itunes", :keyword => keyword)
76
+ # end
77
+ # end
78
+ #
79
+ #
80
+ #
81
+ # end
@@ -0,0 +1,29 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+ require 'flexmock/test_unit'
5
+ require 'fakeweb'
6
+
7
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'bitly')
8
+
9
+ FakeWeb.allow_net_connect = false
10
+
11
+ def fixture_file(filename)
12
+ return '' if filename == ''
13
+ file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
14
+ File.read(file_path)
15
+ end
16
+
17
+ def stub_get(url, filename, status=nil)
18
+ options = {:body => fixture_file(filename)}
19
+ options.merge!({:status => status}) unless status.nil?
20
+
21
+ FakeWeb.register_uri(:get, url, options)
22
+ end
23
+
24
+ def api_key
25
+ 'test_key'
26
+ end
27
+ def login
28
+ 'test_account'
29
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erkki-bitly
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ platform: ruby
6
+ authors:
7
+ - Phil Nash
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-09 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: crack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.1
24
+ version:
25
+ description: Use the bit.ly API to shorten or expand URLs
26
+ email: philnash@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - lib/bitly/client.rb
33
+ - lib/bitly/url.rb
34
+ - lib/bitly/utils.rb
35
+ - lib/bitly/version.rb
36
+ - lib/bitly.rb
37
+ - README.txt
38
+ files:
39
+ - bitly.gemspec
40
+ - History.txt
41
+ - lib/bitly/client.rb
42
+ - lib/bitly/url.rb
43
+ - lib/bitly/utils.rb
44
+ - lib/bitly/version.rb
45
+ - lib/bitly.rb
46
+ - Manifest
47
+ - Rakefile
48
+ - README.txt
49
+ - test/test_bitly.rb
50
+ - test/bitly/test_client.rb
51
+ - test/bitly/test_url.rb
52
+ - test/bitly/test_utils.rb
53
+ - test/test_helper.rb
54
+ has_rdoc: false
55
+ homepage: http://github.com/philnash/bitly
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --line-numbers
59
+ - --inline-source
60
+ - --title
61
+ - Bitly
62
+ - --main
63
+ - README.txt
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "1.2"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project: bitly
81
+ rubygems_version: 1.2.0
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Use the bit.ly API to shorten or expand URLs
85
+ test_files:
86
+ - test/bitly/test_client.rb
87
+ - test/bitly/test_url.rb
88
+ - test/bitly/test_utils.rb
89
+ - test/test_bitly.rb
90
+ - test/test_helper.rb