powertrack 1.0.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.
@@ -0,0 +1,3 @@
1
+ module PowerTrack
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'powertrack/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'powertrack'
8
+ spec.version = PowerTrack::VERSION
9
+ spec.authors = ['Laurent Farcy', 'Eric Wendelin', 'Ryan Weald']
10
+ spec.email = ['laurent.farcy@ecairn.com', 'me@eriwen.com', 'ryan@weald.com']
11
+ spec.summary = %q{Powertrack-rb is a gem used to develop GNIP PowerTrack streaming clients.}
12
+ spec.description = spec.summary
13
+ spec.homepage = 'https://github.com/ecairn/powertrack-rb'
14
+ spec.license = 'MIT license'
15
+ spec.required_ruby_version = '~> 1.9'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.7'
23
+ spec.add_development_dependency 'rake', '~> 10.3'
24
+ spec.add_development_dependency 'minitest', '~> 5.5'
25
+ spec.add_development_dependency 'ruby-prof', '~> 0.15'
26
+
27
+ spec.add_dependency 'multi_json', '~> 1.11'
28
+ spec.add_dependency 'eventmachine', '~> 1.0'
29
+ spec.add_dependency 'em-http-request', '~> 1.1'
30
+ spec.add_dependency 'exponential-backoff', '~> 0.0.2'
31
+ spec.add_dependency 'void_logger', '~> 0.1'
32
+ end
@@ -0,0 +1,41 @@
1
+ gem 'minitest'
2
+ require 'minitest/autorun'
3
+ require 'yaml'
4
+
5
+ class Minitest::Test
6
+
7
+ POWERTRACK_CONFIG_FILEPATH = File.join(File.dirname(__FILE__), "powertrack.yml")
8
+
9
+ # Returns the PowerTrack configuration as defined in test/powertrack.yml.
10
+ def powertrack_config
11
+ unless defined?(@loaded) && @loaded
12
+ begin
13
+ if File.exist?(POWERTRACK_CONFIG_FILEPATH)
14
+ @pwtk_config = (YAML.load_file(POWERTRACK_CONFIG_FILEPATH) || {})
15
+ else
16
+ $stderr.puts "No PowerTrack config file found at '#{POWERTRACK_CONFIG_FILEPATH}'"
17
+ end
18
+ rescue Exception
19
+ $stderr.puts "Exception while loading PowerTrack config file: #{$!.message}"
20
+ ensure
21
+ @pwtk_config ||= {}
22
+ end
23
+
24
+ # symbolize keys
25
+ @pwtk_config = Hash[@pwtk_config.map{ |k, v| [k.to_sym, v] }]
26
+ @loaded = true
27
+ end
28
+
29
+ @pwtk_config
30
+ end
31
+
32
+ # Returns a brand-new stream based on the config found in test/powertrack.yml.
33
+ def new_stream
34
+ PowerTrack::Stream.new(
35
+ powertrack_config[:username],
36
+ powertrack_config[:password],
37
+ powertrack_config[:account_name],
38
+ powertrack_config[:data_source],
39
+ powertrack_config[:stream_label])
40
+ end
41
+ end
@@ -0,0 +1,30 @@
1
+ require 'minitest_helper'
2
+ require 'powertrack'
3
+ require 'multi_json'
4
+
5
+ class TestManageRules < Minitest::Test
6
+
7
+ def test_add_then_delete_a_single_rule
8
+ stream = new_stream
9
+
10
+ rule = PowerTrack::Rule.new('coke')
11
+ assert rule.valid?
12
+
13
+ pre_existing_rules = stream.list_rules
14
+ assert pre_existing_rules.is_a?(Array)
15
+
16
+ assert_nil stream.add_rule(rule)
17
+
18
+ rules_after_addition = stream.list_rules(false)
19
+ assert rules_after_addition.is_a?(Array)
20
+ assert_equal pre_existing_rules.size + 1, rules_after_addition.size
21
+ assert [ rule ], rules_after_addition - pre_existing_rules
22
+
23
+ assert_nil stream.delete_rules(rule)
24
+
25
+ rules_after_removal = stream.list_rules
26
+ assert rules_after_removal.is_a?(Array)
27
+ assert_equal rules_after_addition.size - 1, rules_after_removal.size
28
+ assert_equal [], rules_after_removal - rules_after_addition
29
+ end
30
+ end
data/test/test_rule.rb ADDED
@@ -0,0 +1,163 @@
1
+ require 'minitest_helper'
2
+ require 'powertrack'
3
+ require 'multi_json'
4
+
5
+ class TestRule < Minitest::Test
6
+
7
+ def test_valid_rule
8
+ rule = PowerTrack::Rule.new('coke')
9
+ assert_equal 'coke', rule.value
10
+ assert_nil rule.tag
11
+ assert !rule.long?
12
+ assert rule.valid?
13
+ assert_nil rule.error
14
+
15
+ rule = PowerTrack::Rule.new('pepsi', 'soda', true)
16
+ assert_equal 'pepsi', rule.value
17
+ assert_equal 'soda', rule.tag
18
+ assert rule.long?
19
+ assert rule.valid?
20
+ assert_nil rule.error
21
+ end
22
+
23
+ def test_too_long_tag
24
+ long_tag = 'a' * PowerTrack::Rule::MAX_TAG_LENGTH
25
+ rule = PowerTrack::Rule.new('coke', long_tag, false)
26
+ assert rule.valid?
27
+ assert_nil rule.error
28
+
29
+ long_tag = 'b' * 2 * PowerTrack::Rule::MAX_TAG_LENGTH
30
+ rule = PowerTrack::Rule.new('coke', long_tag, true)
31
+ assert !rule.valid?
32
+ assert_match /too long tag/i, rule.error
33
+ end
34
+
35
+ def test_too_long_value
36
+ long_val = 'a' * PowerTrack::Rule::MAX_STD_RULE_VALUE_LENGTH
37
+ rule = PowerTrack::Rule.new(long_val)
38
+ assert rule.valid?
39
+
40
+ long_val = 'c' * PowerTrack::Rule::MAX_LONG_RULE_VALUE_LENGTH
41
+ rule = long_val.to_pwtk_rule(nil, false)
42
+
43
+ assert !rule.valid?
44
+ assert_match /too long value/i, rule.error
45
+
46
+ assert long_val.to_pwtk_rule.valid?
47
+ assert long_val.to_pwtk_rule(nil, true).valid?
48
+
49
+ very_long_val = 'rrr' * PowerTrack::Rule::MAX_LONG_RULE_VALUE_LENGTH
50
+ rule = very_long_val.to_pwtk_rule
51
+ assert !rule.valid?
52
+ assert_match /too long value/i, rule.error
53
+ end
54
+
55
+ def test_too_many_positive_terms
56
+ phrase = ([ 'coke' ] * PowerTrack::Rule::MAX_POSITIVE_TERMS).join(' ')
57
+ rule = PowerTrack::Rule.new(phrase)
58
+ assert !rule.long?
59
+ assert rule.valid?
60
+ assert_nil rule.error
61
+
62
+ long_rule = PowerTrack::Rule.new(phrase, nil, true)
63
+ assert long_rule.long?
64
+ assert long_rule.valid?
65
+ assert_nil long_rule.error
66
+
67
+ phrase = ([ 'coke' ] * (2 * PowerTrack::Rule::MAX_POSITIVE_TERMS)).join(' ')
68
+ rule = PowerTrack::Rule.new(phrase, nil, false)
69
+ assert !rule.long?
70
+ assert !rule.valid?
71
+ assert_match /too many positive terms/i, rule.error
72
+
73
+ long_rule = PowerTrack::Rule.new(phrase, nil, true)
74
+ assert long_rule.long?
75
+ assert long_rule.valid?
76
+ assert_nil long_rule.error
77
+
78
+ phrase = "from:lkv1csayp OR from:u42vf OR from:y OR from:groj OR from:69iqciuxlxerqq OR from:4 OR from:9832xjrqi1ncrs OR from:7kfss6jxtl0oj OR from:b31m9qf0u3tc OR from:0 OR from:abo59n OR from:3lma3kl OR from:5 OR from:ovw7bgov OR from:ubp OR from:gc9a6b OR from:jo7ootfvy4 OR from:sg7oohj OR from:349ankku OR from:9b72n OR from:qz7offt5019u OR from:gkd OR from:cc31p3 OR from:xws9 OR from:bjzbatm OR from:rwjm78cgre3j5 OR from:f1obak7w3w OR from:nontf OR from:4aeas6kgb7nia OR from:dzqy7"
79
+ long_rule = PowerTrack::Rule.new(phrase)
80
+ assert !long_rule.long?
81
+ assert long_rule.valid?, long_rule.error
82
+ assert_nil long_rule.error
83
+
84
+ long_rule = PowerTrack::Rule.new(phrase + " OR from:michel")
85
+ assert !rule.valid?
86
+ assert_match /too many positive terms/i, rule.error
87
+ end
88
+
89
+ def test_too_many_negative_terms
90
+ phrase = ([ '-pepsi' ] * PowerTrack::Rule::MAX_POSITIVE_TERMS).join(' ')
91
+ rule = PowerTrack::Rule.new(phrase)
92
+ assert !rule.long?
93
+ assert rule.valid?
94
+ assert_nil rule.error
95
+
96
+ long_rule = PowerTrack::Rule.new(phrase, nil, true)
97
+ assert long_rule.long?
98
+ assert long_rule.valid?
99
+ assert_nil long_rule.error
100
+
101
+ phrase = ([ '-pepsi' ] * (2 * PowerTrack::Rule::MAX_POSITIVE_TERMS)).join(' ')
102
+ rule = PowerTrack::Rule.new(phrase)
103
+ assert !rule.long?
104
+ assert !rule.valid?
105
+ assert_match /too many negative terms/i, rule.error
106
+
107
+ long_rule = PowerTrack::Rule.new(phrase, nil, true)
108
+ assert long_rule.long?
109
+ assert long_rule.valid?
110
+ assert_nil long_rule.error
111
+ end
112
+
113
+ def test_contains_negated_or
114
+ phrase = 'coke OR -pepsi'
115
+ rule = PowerTrack::Rule.new(phrase)
116
+ assert !rule.long?
117
+ assert !rule.valid?
118
+ assert_match /contains negated or/i, rule.error
119
+ end
120
+
121
+ def test_to_hash_and_json
122
+ res = { value: 'coke OR pepsi' }
123
+ rule = PowerTrack::Rule.new(res[:value])
124
+ assert_equal res, rule.to_hash
125
+ assert_equal MultiJson.encode(res), rule.to_json
126
+
127
+ res[:tag] = 'soda'
128
+ rule = PowerTrack::Rule.new(res[:value], res[:tag], true)
129
+ assert_equal res, rule.to_hash
130
+ assert_equal MultiJson.encode(res), rule.to_json
131
+ end
132
+
133
+ def test_double_quote_jsonification
134
+ rule = PowerTrack::Rule.new('"social data" @gnip')
135
+ assert_equal '{"value":"\"social data\" @gnip"}', rule.to_json
136
+
137
+ rule = PowerTrack::Rule.new('Toys \"R\" Us')
138
+ # 2 backslashes for 1
139
+ assert_equal '{"value":"Toys \\\\\\"R\\\\\\" Us"}', rule.to_json
140
+ end
141
+
142
+ def test_hash
143
+ short_rule = PowerTrack::Rule.new('coke')
144
+ not_long_rule = PowerTrack::Rule.new('coke', nil, false)
145
+ false_long_rule = PowerTrack::Rule.new('coke', nil, true)
146
+ short_rule_with_tag = PowerTrack::Rule.new('coke', 'soda')
147
+
148
+ assert short_rule == not_long_rule
149
+ assert_equal short_rule, not_long_rule
150
+ assert_equal short_rule.hash, not_long_rule.hash
151
+
152
+ assert short_rule != false_long_rule
153
+ h = { short_rule => 1 }
154
+ h[not_long_rule] = 2
155
+ h[false_long_rule] = 3
156
+ h[short_rule_with_tag] = 4
157
+
158
+ assert_equal 2, h[short_rule]
159
+ assert_equal h[short_rule], h[not_long_rule]
160
+ assert_equal 4, h[short_rule_with_tag]
161
+ assert_nil h[PowerTrack::Rule.new('pepsi', 'soda')]
162
+ end
163
+ end
@@ -0,0 +1,72 @@
1
+ require 'minitest_helper'
2
+ require 'powertrack'
3
+ require 'multi_json'
4
+
5
+ class TestTrackStream < Minitest::Test
6
+
7
+ def test_track_simple_stream
8
+ stream = new_stream
9
+
10
+ # add a logger
11
+ stream.logger = Logger.new(STDERR)
12
+
13
+ rule = PowerTrack::Rule.new('ny OR nyc OR #nyc OR new york')
14
+ assert rule.valid?
15
+
16
+ begin
17
+ assert_nil stream.add_rule(rule)
18
+ rules_after_addition = stream.list_rules
19
+ assert rules_after_addition.is_a?(Array)
20
+ assert rules_after_addition.size > 0
21
+
22
+ heartbeats = 0
23
+ received = 0
24
+ tweeted = 0
25
+ closed = false
26
+
27
+ # ready to track
28
+ on_message = lambda do |message|
29
+ received += 1
30
+ end
31
+ on_heartbeat = lambda do
32
+ heartbeats += 1
33
+ end
34
+ on_activity = lambda do |tweet|
35
+ tweeted += 1
36
+ end
37
+
38
+ close_now = lambda { closed }
39
+
40
+ delay = 60
41
+ Thread.new do
42
+ $stderr.puts "Time-bomb thread running for #{delay} seconds..."
43
+ sleep delay
44
+ $stderr.puts "Time to shut down !"
45
+ closed = true
46
+ end
47
+
48
+ started_at = Time.now
49
+ res = stream.track(on_message: on_message,
50
+ on_heartbeat: on_heartbeat,
51
+ on_activity: on_activity,
52
+ close_now: close_now,
53
+ max_retries: 3,
54
+ fake_disconnections: 20)
55
+
56
+ assert_nil res
57
+ assert closed, 'Stream not closed'
58
+ assert Time.now - started_at >= delay
59
+
60
+ assert heartbeats > 0, 'No heartbeat received'
61
+ puts "#{heartbeats} heartbeats received"
62
+
63
+ assert received > 0, 'No message received so far'
64
+ puts "#{received} messages received"
65
+
66
+ assert tweeted > 0, 'No tweet received so far'
67
+ puts "#{tweeted} tweets received"
68
+ ensure
69
+ assert_nil stream.delete_rules(rule)
70
+ end
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,202 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: powertrack
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Laurent Farcy
8
+ - Eric Wendelin
9
+ - Ryan Weald
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2015-08-18 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.7'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: '1.7'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: '10.3'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: '10.3'
43
+ - !ruby/object:Gem::Dependency
44
+ name: minitest
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ version: '5.5'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: '5.5'
57
+ - !ruby/object:Gem::Dependency
58
+ name: ruby-prof
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '0.15'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: '0.15'
71
+ - !ruby/object:Gem::Dependency
72
+ name: multi_json
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.11'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ~>
83
+ - !ruby/object:Gem::Version
84
+ version: '1.11'
85
+ - !ruby/object:Gem::Dependency
86
+ name: eventmachine
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ version: !binary |-
92
+ MS4w
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: !binary |-
100
+ MS4w
101
+ - !ruby/object:Gem::Dependency
102
+ name: em-http-request
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ~>
106
+ - !ruby/object:Gem::Version
107
+ version: '1.1'
108
+ type: :runtime
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ~>
113
+ - !ruby/object:Gem::Version
114
+ version: '1.1'
115
+ - !ruby/object:Gem::Dependency
116
+ name: exponential-backoff
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ~>
120
+ - !ruby/object:Gem::Version
121
+ version: 0.0.2
122
+ type: :runtime
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ~>
127
+ - !ruby/object:Gem::Version
128
+ version: 0.0.2
129
+ - !ruby/object:Gem::Dependency
130
+ name: void_logger
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ~>
134
+ - !ruby/object:Gem::Version
135
+ version: '0.1'
136
+ type: :runtime
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ~>
141
+ - !ruby/object:Gem::Version
142
+ version: '0.1'
143
+ description: Powertrack-rb is a gem used to develop GNIP PowerTrack streaming clients.
144
+ email:
145
+ - laurent.farcy@ecairn.com
146
+ - me@eriwen.com
147
+ - ryan@weald.com
148
+ executables: []
149
+ extensions: []
150
+ extra_rdoc_files: []
151
+ files:
152
+ - .gitignore
153
+ - Gemfile
154
+ - Gemfile.lock
155
+ - LICENSE.md
156
+ - README.md
157
+ - Rakefile
158
+ - TODO.md
159
+ - lib/core_ext/class.rb
160
+ - lib/powertrack.rb
161
+ - lib/powertrack/errors.rb
162
+ - lib/powertrack/rules/rule.rb
163
+ - lib/powertrack/rules/string_extension.rb
164
+ - lib/powertrack/streaming/api.rb
165
+ - lib/powertrack/streaming/data_buffer.rb
166
+ - lib/powertrack/streaming/retrier.rb
167
+ - lib/powertrack/streaming/stream.rb
168
+ - lib/powertrack/version.rb
169
+ - powertrack.gemspec
170
+ - test/minitest_helper.rb
171
+ - test/test_manage_rules.rb
172
+ - test/test_rule.rb
173
+ - test/test_track_stream.rb
174
+ homepage: https://github.com/ecairn/powertrack-rb
175
+ licenses:
176
+ - MIT license
177
+ metadata: {}
178
+ post_install_message:
179
+ rdoc_options: []
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ~>
185
+ - !ruby/object:Gem::Version
186
+ version: '1.9'
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ! '>='
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 2.4.6
195
+ signing_key:
196
+ specification_version: 4
197
+ summary: Powertrack-rb is a gem used to develop GNIP PowerTrack streaming clients.
198
+ test_files:
199
+ - test/minitest_helper.rb
200
+ - test/test_manage_rules.rb
201
+ - test/test_rule.rb
202
+ - test/test_track_stream.rb