virility 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +83 -17
- data/lib/virility.rb +35 -3
- data/lib/virility/exceptions.rb +5 -0
- data/lib/virility/excitation.rb +26 -40
- data/lib/virility/strategies/delicious.rb +7 -8
- data/lib/virility/strategies/facebook.rb +12 -5
- data/lib/virility/strategies/pinterest.rb +8 -9
- data/lib/virility/strategies/plus_one.rb +4 -5
- data/lib/virility/strategies/stumble_upon.rb +4 -5
- data/lib/virility/strategies/twitter.rb +4 -5
- data/lib/virility/strategy.rb +98 -0
- data/lib/virility/supporter.rb +55 -0
- data/lib/virility/version.rb +1 -1
- data/spec/excitation_spec.rb +58 -33
- data/spec/spec_helper.rb +27 -0
- data/spec/strategies/delicious_spec.rb +66 -0
- data/spec/strategies/facebook_spec.rb +98 -0
- data/spec/strategies/pinterest_spec.rb +66 -0
- data/spec/strategies/plus_one_spec.rb +66 -0
- data/spec/strategies/stumble_upon_spec.rb +66 -0
- data/spec/strategies/twitter_spec.rb +66 -0
- data/spec/strategy_spec.rb +102 -0
- data/spec/virility_spec.rb +70 -1
- data/virility.gemspec +1 -1
- metadata +22 -8
- data/lib/virility/context.rb +0 -18
- data/spec/context_spec.rb +0 -31
@@ -0,0 +1,98 @@
|
|
1
|
+
module Virility
|
2
|
+
class Strategy
|
3
|
+
include HTTParty
|
4
|
+
include Virility::Supporter
|
5
|
+
|
6
|
+
attr_accessor :url, :response, :results
|
7
|
+
|
8
|
+
def initialize url
|
9
|
+
@url = encode url
|
10
|
+
@results = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Abstract Methods - Delete eventually
|
15
|
+
#
|
16
|
+
|
17
|
+
def census
|
18
|
+
raise "Abstract Method census called on #{self.class} - Please define this method"
|
19
|
+
end
|
20
|
+
|
21
|
+
def count
|
22
|
+
raise "Abstract Method count called on #{self.class} - Please define this method"
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Poll
|
27
|
+
#
|
28
|
+
|
29
|
+
def poll
|
30
|
+
call_strategy
|
31
|
+
collect_results
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Call Strategy
|
36
|
+
#
|
37
|
+
|
38
|
+
def call_strategy
|
39
|
+
@response = census
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Results
|
44
|
+
#
|
45
|
+
|
46
|
+
def collect_results
|
47
|
+
if respond_to?(:outcome)
|
48
|
+
@results = valid_response_test ? outcome : {}
|
49
|
+
else
|
50
|
+
@results = valid_response_test ? @response.parsed_response : {}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def results
|
55
|
+
if @results.empty?
|
56
|
+
begin
|
57
|
+
poll
|
58
|
+
rescue => e
|
59
|
+
puts "[virility#poll] #{self.class.to_s} => #{e}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
@results
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Dynamic Methods
|
67
|
+
#
|
68
|
+
|
69
|
+
def get_result key
|
70
|
+
if result_exists?(key)
|
71
|
+
results[key.to_s]
|
72
|
+
else
|
73
|
+
0
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def result_exists? key
|
78
|
+
!results[key.to_s].nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def method_missing(name, *args, &block)
|
82
|
+
if result_exists?(name)
|
83
|
+
get_result(name)
|
84
|
+
else
|
85
|
+
0
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Parsed Response Test - Overwrite if needed
|
91
|
+
#
|
92
|
+
|
93
|
+
def valid_response_test
|
94
|
+
@response.respond_to?(:parsed_response) and @response.parsed_response.is_a?(Hash)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Virility
|
2
|
+
module Supporter
|
3
|
+
|
4
|
+
#
|
5
|
+
# URL Encoding / Decoding Methods
|
6
|
+
#
|
7
|
+
|
8
|
+
def encode url
|
9
|
+
CGI.escape url
|
10
|
+
end
|
11
|
+
|
12
|
+
def url
|
13
|
+
CGI.unescape @url
|
14
|
+
end
|
15
|
+
|
16
|
+
def escaped_url
|
17
|
+
@url
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Camelize / Underscore
|
22
|
+
#
|
23
|
+
|
24
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
25
|
+
if first_letter_in_uppercase
|
26
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
27
|
+
else
|
28
|
+
lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def underscore(camel_cased_word)
|
33
|
+
word = camel_cased_word.to_s.dup
|
34
|
+
word.gsub!(/::/, '/')
|
35
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
36
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
37
|
+
word.tr!("-", "_")
|
38
|
+
word.downcase!
|
39
|
+
word
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Convert Class Name To Appropriate Key Symbol
|
44
|
+
#
|
45
|
+
|
46
|
+
def symbolize_for_key(klass)
|
47
|
+
underscore(klass.class.to_s.gsub(/Virility::/, '')).to_sym
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_class_string(klass)
|
51
|
+
File.basename(klass).gsub(/\.rb/,'')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
data/lib/virility/version.rb
CHANGED
data/spec/excitation_spec.rb
CHANGED
@@ -2,9 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe "Excitation" do
|
4
4
|
before(:each) do
|
5
|
-
@url = "http://
|
5
|
+
@url = "http://creativeallies.com"
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
#
|
9
9
|
# Initialization
|
10
10
|
#
|
@@ -13,12 +13,8 @@ describe "Excitation" do
|
|
13
13
|
it "should raise an error if a URL is not set" do
|
14
14
|
lambda {Virility::Excitation.new}.should raise_error
|
15
15
|
end
|
16
|
-
|
17
|
-
it "should automatically encode the url" do
|
18
|
-
Virility::Excitation.new(@url).attributes[:url].should == "http%3A%2F%2Fwww.dzone.com%2Fsnippets%2Furi-encoding-ruby"
|
19
|
-
end
|
20
16
|
end
|
21
|
-
|
17
|
+
|
22
18
|
#
|
23
19
|
# Get Virility
|
24
20
|
#
|
@@ -37,11 +33,11 @@ describe "Excitation" do
|
|
37
33
|
it "should assign a hash to the strategies variable" do
|
38
34
|
Virility::Excitation.new(@url).strategies.should be_a_kind_of Hash
|
39
35
|
end
|
40
|
-
|
41
|
-
it "strategies should be inherited from the
|
42
|
-
Virility::Excitation.new(@url).strategies.first.last.should be_a_kind_of Virility::
|
36
|
+
|
37
|
+
it "strategies should be inherited from the Strategy" do
|
38
|
+
Virility::Excitation.new(@url).strategies.first.last.should be_a_kind_of Virility::Strategy
|
43
39
|
end
|
44
|
-
|
40
|
+
|
45
41
|
it "should load all of the strategies" do
|
46
42
|
Virility::Excitation.new(@url).strategies.count.should == Dir[File.join('lib', 'virility', 'strategies', '**', '*')].count { |file| File.file?(file) }
|
47
43
|
end
|
@@ -54,38 +50,67 @@ describe "Excitation" do
|
|
54
50
|
context "encode" do
|
55
51
|
it "should encode the url" do
|
56
52
|
v = Virility::Excitation.new(@url)
|
57
|
-
v.encode(@url).should == "http%3A%2F%
|
53
|
+
v.encode(@url).should == "http%3A%2F%2Fcreativeallies.com"
|
58
54
|
end
|
59
55
|
end
|
60
|
-
|
56
|
+
|
61
57
|
#
|
62
|
-
#
|
58
|
+
# Symbolize For Key
|
63
59
|
#
|
64
60
|
|
65
|
-
context "
|
66
|
-
it "should return the
|
67
|
-
Virility::Excitation.new(@url).url.should ==
|
61
|
+
context "symbolize_for_key" do
|
62
|
+
it "should return a symbol with the name of the class" do
|
63
|
+
Virility::Excitation.new(@url).symbolize_for_key(Virility::Excitation.new(@url)).should == :excitation
|
68
64
|
end
|
69
65
|
end
|
70
|
-
|
66
|
+
|
71
67
|
#
|
72
|
-
#
|
68
|
+
# Dynamic Methods
|
73
69
|
#
|
74
70
|
|
75
|
-
|
76
|
-
|
77
|
-
Virility::
|
71
|
+
describe "dynamic methods" do
|
72
|
+
context "overall testing" do
|
73
|
+
Virility::TESTING_STRATEGIES.each do |method, klass|
|
74
|
+
it "should return a #{klass} object when the method #{method} is called" do
|
75
|
+
Virility::Excitation.new(@url).send(method).should be_a_kind_of klass
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Virility::FAKE_TESTING_STRATEGIES.each do |method|
|
80
|
+
it "should raise an error if the strategy (#{method}) does not exist" do
|
81
|
+
lambda { Virility::Excitation.new(@url).send(method) }.should raise_error(Virility::UnknownStrategy, "#{method} Is Not A Known Strategy")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "strategy_exists?" do
|
87
|
+
Virility::TESTING_STRATEGIES.keys.each do |strategy|
|
88
|
+
it "should return true for #{strategy}" do
|
89
|
+
Virility::Excitation.new(@url).strategy_exists?(strategy).should be true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
Virility::FAKE_TESTING_STRATEGIES.each do |strategy|
|
94
|
+
it "should return false for #{strategy}" do
|
95
|
+
Virility::Excitation.new(@url).strategy_exists?(strategy).should be false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "get_strategy" do
|
101
|
+
Virility::TESTING_STRATEGIES.each do |method, klass|
|
102
|
+
it "should return a #{klass} object when get_strategy is called with #{method}" do
|
103
|
+
Virility::Excitation.new(@url).get_strategy(method).should be_a_kind_of klass
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Virility::FAKE_TESTING_STRATEGIES.each do |method|
|
108
|
+
it "should raise an error if the strategy (#{method}) does not exist" do
|
109
|
+
lambda { Virility::Excitation.new(@url).get_strategy(method) }.should raise_error(Virility::UnknownStrategy, "#{method} Is Not A Known Strategy")
|
110
|
+
end
|
111
|
+
end
|
78
112
|
end
|
79
|
-
end
|
80
113
|
|
81
|
-
#
|
82
|
-
# Symbolize For Key
|
83
|
-
#
|
84
|
-
|
85
|
-
context "symbolize_for_key" do
|
86
|
-
it "should return a symbol with the name of the class" do
|
87
|
-
Virility::Excitation.new(@url).symbolize_for_key(Virility::Excitation.new(@url)).should == :excitation
|
88
|
-
end
|
89
114
|
end
|
90
|
-
|
91
|
-
end
|
115
|
+
|
116
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -11,4 +11,31 @@ RSpec.configure do |config|
|
|
11
11
|
config.filter_run :focus => true
|
12
12
|
config.run_all_when_everything_filtered = true
|
13
13
|
config.mock_with :rspec
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Constants for Testing
|
18
|
+
#
|
19
|
+
|
20
|
+
module Virility
|
21
|
+
TESTING_STRATEGIES = {:facebook => Virility::Facebook, :twitter => Virility::Twitter, :delicious => Virility::Delicious, :pinterest => Virility::Pinterest, :plus_one => Virility::PlusOne, :stumble_upon => Virility::StumbleUpon}
|
22
|
+
FAKE_TESTING_STRATEGIES = [:digg, :reddit, :linked_in, :instagram, :tumblr]
|
23
|
+
|
24
|
+
FB_RESULTS = {"like_count"=>"19", "click_count"=>"0", "share_count"=>"3", "comment_count"=>"0", "commentsbox_count"=>"0", "total_count"=>"22"}
|
25
|
+
FAKE_FB_RESULTS = [:face_count, :pages, :friends]
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
#
|
30
|
+
# Example Groups
|
31
|
+
#
|
32
|
+
|
33
|
+
share_examples_for "no context results" do
|
34
|
+
it "should not raise an error" do
|
35
|
+
lambda { @virility.poll }.should_not raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return 0 for count" do
|
39
|
+
@virility.count.should == 0
|
40
|
+
end
|
14
41
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "Virility::Delicious" do
|
4
|
+
before(:each) do
|
5
|
+
@url = "http://creativeallies.com"
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "poll" do
|
9
|
+
context "when there is not a valid result" do
|
10
|
+
before(:each) do
|
11
|
+
response = double("HTTParty::Response", :parsed_response => {"fake_return_value"=> "OICU812"})
|
12
|
+
Virility::Delicious.stub(:get).and_return(response)
|
13
|
+
@virility = Virility::Delicious.new(@url)
|
14
|
+
end
|
15
|
+
|
16
|
+
it_should_behave_like "no context results"
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when there is no result" do
|
20
|
+
before(:each) do
|
21
|
+
response = double("HTTParty::Response")
|
22
|
+
Virility::Delicious.stub(:get).and_return(response)
|
23
|
+
@virility = Virility::Delicious.new(@url)
|
24
|
+
end
|
25
|
+
|
26
|
+
it_should_behave_like "no context results"
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when there is a result but no specific hash value" do
|
30
|
+
before(:each) do
|
31
|
+
response = double("HTTParty::Response", :parsed_response => {})
|
32
|
+
Virility::Delicious.stub(:get).and_return(response)
|
33
|
+
@virility = Virility::Delicious.new(@url)
|
34
|
+
end
|
35
|
+
|
36
|
+
it_should_behave_like "no context results"
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when there is a result but parsed_response is weird" do
|
40
|
+
before(:each) do
|
41
|
+
response = double("HTTParty::Response", :parsed_response => Object.new)
|
42
|
+
Virility::Delicious.stub(:get).and_return(response)
|
43
|
+
@virility = Virility::Delicious.new(@url)
|
44
|
+
end
|
45
|
+
|
46
|
+
it_should_behave_like "no context results"
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when there is a valid result" do
|
50
|
+
before(:each) do
|
51
|
+
response = double("HTTParty::Response", :parsed_response => {"url"=>"http://creativeallies.com/", "total_posts"=>50, "top_tags"=>{"graphic"=>1, "art"=>1, "contest"=>1, "photography"=>1, "creativity"=>1, "design"=>1, "online"=>1, "music"=>1, "contests"=>1, "freelance"=>1}, "hash"=>"f9468b2d2842d4a9685af46e1b8e9349", "title"=>"Creative Allies | Create Art For Rockstars"})
|
52
|
+
Virility::Delicious.stub(:get).and_return(response)
|
53
|
+
@virility = Virility::Delicious.new(@url)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not raise an error" do
|
57
|
+
lambda { @virility.poll }.should_not raise_error
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return 50 for the count" do
|
61
|
+
@virility.count.should == 50
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "Virility::Facebook" do
|
4
|
+
before(:each) do
|
5
|
+
@url = "http://creativeallies.com"
|
6
|
+
end
|
7
|
+
|
8
|
+
share_examples_for "no facebook results" do
|
9
|
+
it "should not raise an error" do
|
10
|
+
lambda { @virility.poll }.should_not raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
["like_count", "click_count", "share_count", "comment_count", "commentsbox_count", "total_count"].each do |attribute|
|
14
|
+
it "should return 0 for #{attribute}" do
|
15
|
+
@virility.send(attribute.to_sym).should == 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "poll" do
|
21
|
+
context "when there is not a valid result" do
|
22
|
+
before(:each) do
|
23
|
+
response = double("HTTParty::Response", :parsed_response => {"fql_query_response"=>{"list"=>"true"}})
|
24
|
+
Virility::Facebook.stub(:get).and_return(response)
|
25
|
+
@virility = Virility::Facebook.new(@url)
|
26
|
+
end
|
27
|
+
|
28
|
+
it_should_behave_like "no facebook results"
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when there is no result" do
|
32
|
+
before(:each) do
|
33
|
+
response = double("HTTParty::Response")
|
34
|
+
Virility::Facebook.stub(:get).and_return(response)
|
35
|
+
@virility = Virility::Facebook.new(@url)
|
36
|
+
end
|
37
|
+
|
38
|
+
it_should_behave_like "no facebook results"
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when there is a result but no fql_query_response" do
|
42
|
+
before(:each) do
|
43
|
+
response = double("HTTParty::Response", :parsed_response => {})
|
44
|
+
Virility::Facebook.stub(:get).and_return(response)
|
45
|
+
@virility = Virility::Facebook.new(@url)
|
46
|
+
end
|
47
|
+
|
48
|
+
it_should_behave_like "no facebook results"
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when there is a result but parsed_response is weird" do
|
52
|
+
before(:each) do
|
53
|
+
response = double("HTTParty::Response", :parsed_response => Object.new)
|
54
|
+
Virility::Facebook.stub(:get).and_return(response)
|
55
|
+
@virility = Virility::Facebook.new(@url)
|
56
|
+
end
|
57
|
+
|
58
|
+
it_should_behave_like "no facebook results"
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when there is a valid result" do
|
62
|
+
before(:each) do
|
63
|
+
response = double("HTTParty::Response", :parsed_response => {"fql_query_response"=>{"list"=>"true", "link_stat"=>{"like_count"=>"977662", "click_count"=>"265614", "share_count"=>"3020040", "comment_count"=>"1118601", "commentsbox_count"=>"0", "total_count"=>"5116303"}}})
|
64
|
+
Virility::Facebook.stub(:get).and_return(response)
|
65
|
+
@virility = Virility::Facebook.new(@url)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should not raise an error" do
|
69
|
+
lambda { @virility.poll }.should_not raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
{"like_count"=>"977662", "click_count"=>"265614", "share_count"=>"3020040", "comment_count"=>"1118601", "commentsbox_count"=>"0", "total_count"=>"5116303"}.each do |key, value|
|
73
|
+
it "should return #{value} for #{key}" do
|
74
|
+
@virility.send(key.to_sym).should == value
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when there is a valid result, but not all fields are present" do
|
80
|
+
before(:each) do
|
81
|
+
response = double("HTTParty::Response", :parsed_response => {"fql_query_response"=>{"list"=>"true", "link_stat"=>{"like_count"=>"977662", "comment_count"=>"1118601", "commentsbox_count"=>"0", "total_count"=>"5116303"}}})
|
82
|
+
Virility::Facebook.stub(:get).and_return(response)
|
83
|
+
@virility = Virility::Facebook.new(@url)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should not raise an error" do
|
87
|
+
lambda { @virility.poll }.should_not raise_error
|
88
|
+
end
|
89
|
+
|
90
|
+
{"like_count"=>"977662", "click_count"=>0, "share_count"=>0, "comment_count"=>"1118601", "commentsbox_count"=>"0", "total_count"=>"5116303"}.each do |key, value|
|
91
|
+
it "should return #{value} for #{key}" do
|
92
|
+
@virility.send(key.to_sym).should == value
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|