km 1.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.
Files changed (71) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGELOG +4 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +33 -0
  5. data/README.rdoc +10 -0
  6. data/Rakefile +5 -0
  7. data/bin/km_send +26 -0
  8. data/doc/Accept.html +546 -0
  9. data/doc/Gemfile.html +110 -0
  10. data/doc/Hash.html +283 -0
  11. data/doc/Helper.html +318 -0
  12. data/doc/KM/IdentError.html +159 -0
  13. data/doc/KM/InitError.html +159 -0
  14. data/doc/KM/SaaS.html +451 -0
  15. data/doc/KM.html +493 -0
  16. data/doc/KMError.html +159 -0
  17. data/doc/Object.html +211 -0
  18. data/doc/README_rdoc.html +122 -0
  19. data/doc/Rakefile.html +111 -0
  20. data/doc/String.html +244 -0
  21. data/doc/bin/km_send.html +54 -0
  22. data/doc/created.rid +15 -0
  23. data/doc/images/brick.png +0 -0
  24. data/doc/images/brick_link.png +0 -0
  25. data/doc/images/bug.png +0 -0
  26. data/doc/images/bullet_black.png +0 -0
  27. data/doc/images/bullet_toggle_minus.png +0 -0
  28. data/doc/images/bullet_toggle_plus.png +0 -0
  29. data/doc/images/date.png +0 -0
  30. data/doc/images/find.png +0 -0
  31. data/doc/images/loadingAnimation.gif +0 -0
  32. data/doc/images/macFFBgHack.png +0 -0
  33. data/doc/images/package.png +0 -0
  34. data/doc/images/page_green.png +0 -0
  35. data/doc/images/page_white_text.png +0 -0
  36. data/doc/images/page_white_width.png +0 -0
  37. data/doc/images/plugin.png +0 -0
  38. data/doc/images/ruby.png +0 -0
  39. data/doc/images/tag_green.png +0 -0
  40. data/doc/images/wrench.png +0 -0
  41. data/doc/images/wrench_orange.png +0 -0
  42. data/doc/images/zoom.png +0 -0
  43. data/doc/index.html +142 -0
  44. data/doc/js/darkfish.js +116 -0
  45. data/doc/js/jquery.js +32 -0
  46. data/doc/js/quicksearch.js +114 -0
  47. data/doc/js/thickbox-compressed.js +10 -0
  48. data/doc/lib/km/saas_rb.html +54 -0
  49. data/doc/lib/km/version_rb.html +52 -0
  50. data/doc/lib/km_rb.html +60 -0
  51. data/doc/rdoc.css +730 -0
  52. data/doc/spec/accept_rb.html +62 -0
  53. data/doc/spec/km_old_rb.html +54 -0
  54. data/doc/spec/km_saas_spec_rb.html +56 -0
  55. data/doc/spec/km_send_spec_rb.html +54 -0
  56. data/doc/spec/km_spec_rb.html +54 -0
  57. data/doc/spec/setup_rb.html +60 -0
  58. data/doc/spec/watchr_rb.html +52 -0
  59. data/km.gemspec +28 -0
  60. data/lib/km/saas.rb +39 -0
  61. data/lib/km/version.rb +3 -0
  62. data/lib/km.rb +263 -0
  63. data/spec/accept.rb +90 -0
  64. data/spec/km_old.rb +105 -0
  65. data/spec/km_saas_spec.rb +121 -0
  66. data/spec/km_send_spec.rb +82 -0
  67. data/spec/km_spec.rb +186 -0
  68. data/spec/log/.hold +0 -0
  69. data/spec/setup.rb +78 -0
  70. data/spec/watchr.rb +3 -0
  71. metadata +224 -0
data/spec/km_spec.rb ADDED
@@ -0,0 +1,186 @@
1
+ require 'setup'
2
+ describe KM do
3
+ before do
4
+ KM::reset
5
+ now = Time.now
6
+ Time.stub!(:now).and_return(now)
7
+ FileUtils.rm_f KM::log_name(:error)
8
+ FileUtils.rm_f KM::log_name(:query)
9
+ Helper.clear
10
+ end
11
+ it "shouldn't write at all without init or identify" do
12
+ KM::record 'My Action'
13
+ IO.readlines(KM::log_name(:error)).join.should =~ /Need to initialize first \(KM::init <your_key>\)/
14
+
15
+ FileUtils.rm_f KM::log_name(:error)
16
+ KM::set :day => 'friday'
17
+ IO.readlines(KM::log_name(:error)).join.should =~ /Need to initialize first \(KM::init <your_key>\)/
18
+
19
+ KM::init 'KM_KEY', :log_dir => __('log'), :host => '127.0.0.1:9292'
20
+ FileUtils.rm_f KM::log_name(:error)
21
+ KM::record 'My Action'
22
+ IO.readlines(KM::log_name(:error)).last.should =~ /Need to identify first \(KM::identify <user>\)/
23
+
24
+ FileUtils.rm_f KM::log_name(:error)
25
+ KM::set :day => 'friday'
26
+ IO.readlines(KM::log_name(:error)).last.should =~ /Need to identify first \(KM::identify <user>\)/
27
+ end
28
+
29
+ it "shouldn't fail on alias without identifying" do
30
+ KM::init 'KM_OTHER', :log_dir => __('log'), :host => '127.0.0.1:9292'
31
+ KM::alias 'peter','joe' # Alias "bob" to "robert"
32
+ sleep 0.1
33
+ res = Helper.accept(:history).first.indifferent
34
+ res[:path].should == '/a'
35
+ res[:query]['_k'].first.should == 'KM_OTHER'
36
+ res[:query]['_p'].first.should == 'peter'
37
+ res[:query]['_n'].first.should == 'joe'
38
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
39
+ end
40
+ it "shouldn't fail on alias without identifying from commandline" do
41
+ KM::init 'KM_OTHER', :log_dir => __('log'), :host => '127.0.0.1:9292'
42
+ KM::alias 'peter','joe' # Alias "bob" to "robert"
43
+ sleep 0.1
44
+ res = Helper.accept(:history).first.indifferent
45
+ res[:path].should == '/a'
46
+ res[:query]['_k'].first.should == 'KM_OTHER'
47
+ res[:query]['_p'].first.should == 'peter'
48
+ res[:query]['_n'].first.should == 'joe'
49
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
50
+ end
51
+
52
+ describe "should record events" do
53
+ before do
54
+ KM::init 'KM_KEY', :log_dir => __('log'), :host => '127.0.0.1:9292'
55
+ KM::identify 'bob'
56
+ end
57
+ it "records an action with no action-specific properties" do
58
+ KM::record 'My Action'
59
+ sleep 0.1
60
+ res = Helper.accept(:history).first.indifferent
61
+ res[:path].should == '/e'
62
+ res[:query]['_k'].first.should == 'KM_KEY'
63
+ res[:query]['_p'].first.should == 'bob'
64
+ res[:query]['_n'].first.should == 'My Action'
65
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
66
+ end
67
+ it "records an action with properties" do
68
+ KM::record 'Signup', 'age' => 26
69
+ sleep 0.1
70
+ res = Helper.accept(:history).first.indifferent
71
+ res[:path].should == '/e'
72
+ res[:query]['_k'].first.should == 'KM_KEY'
73
+ res[:query]['_p'].first.should == 'bob'
74
+ res[:query]['_n'].first.should == 'Signup'
75
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
76
+ res[:query]['age'].first.should == 26.to_s
77
+ end
78
+ it "should be able to hace spaces in key and value" do
79
+ KM::record 'Signup', 'age' => 26, 'city of residence' => 'eug ene'
80
+ sleep 0.1
81
+ res = Helper.accept(:history).first.indifferent
82
+ res[:path].should == '/e'
83
+ res[:query]['_k'].first.should == 'KM_KEY'
84
+ res[:query]['_p'].first.should == 'bob'
85
+ res[:query]['_n'].first.should == 'Signup'
86
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
87
+ res[:query]['age'].first.should == 26.to_s
88
+ res[:query]['city of residence'].first.should == 'eug ene'
89
+ end
90
+ it "should not override important parts" do
91
+ KM::record 'Signup', 'age' => 26, '_p' => 'billybob', '_k' => 'foo', '_n' => 'something else'
92
+ sleep 0.1
93
+ res = Helper.accept(:history).first.indifferent
94
+ res[:path].should == '/e'
95
+ res[:query]['_k'].first.should == 'KM_KEY'
96
+ res[:query]['_p'].first.should == 'bob'
97
+ res[:query]['_n'].first.should == 'Signup'
98
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
99
+ res[:query]['age'].first.should == 26.to_s
100
+ end
101
+ it "should work with propps using @" do
102
+ KM::record 'Signup', 'email' => 'test@blah.com', '_p' => 'billybob', '_k' => 'foo', '_n' => 'something else'
103
+ res = Helper.accept(:history).first.indifferent
104
+ res[:path].should == '/e'
105
+ res[:query]['_k'].first.should == 'KM_KEY'
106
+ res[:query]['_p'].first.should == 'bob'
107
+ res[:query]['_n'].first.should == 'Signup'
108
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
109
+ res[:query]['email'].first.should == 'test@blah.com'
110
+ end
111
+ it "should just set properties without event" do
112
+ KM::record 'age' => 26
113
+ sleep 0.1
114
+ res = Helper.accept(:history).first.indifferent
115
+ res[:path].should == '/s'
116
+ res[:query]['_k'].first.should == 'KM_KEY'
117
+ res[:query]['_p'].first.should == 'bob'
118
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
119
+ res[:query]['age'].first.should == 26.to_s
120
+ end
121
+ it "should be able to use km set directly" do
122
+ KM::set 'age' => 26
123
+ sleep 0.1
124
+ res = Helper.accept(:history).first.indifferent
125
+ res[:path].should == '/s'
126
+ res[:query]['_k'].first.should == 'KM_KEY'
127
+ res[:query]['_p'].first.should == 'bob'
128
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
129
+ res[:query]['age'].first.should == 26.to_s
130
+ end
131
+ it "should work with multiple lines" do
132
+ # testing recording of multiple lines.
133
+ KM::record 'Signup', 'age' => 26
134
+ sleep 0.1
135
+ KM::record 'Signup', 'age' => 36
136
+ sleep 0.1
137
+ res = Helper.accept(:history)[0].indifferent
138
+ res[:path].should == '/e'
139
+ res[:query]['_k'].first.should == 'KM_KEY'
140
+ res[:query]['_p'].first.should == 'bob'
141
+ res[:query]['_n'].first.should == 'Signup'
142
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
143
+ res[:query]['age'].first.should == 26.to_s
144
+ res = Helper.accept(:history)[1].indifferent
145
+ res[:path].should == '/e'
146
+ res[:query]['_k'].first.should == 'KM_KEY'
147
+ res[:query]['_p'].first.should == 'bob'
148
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
149
+ res[:query]['age'].first.should == 36.to_s
150
+ end
151
+ it "should not have key hardcoded anywhere" do
152
+ KM::init 'KM_OTHER', :log_dir => __('log')
153
+ KM::alias 'truman','harry' # Alias "bob" to "robert"
154
+ sleep 0.1
155
+ res = Helper.accept(:history)[0].indifferent
156
+ res[:path].should == '/a'
157
+ res[:query]['_k'].first.should == 'KM_OTHER'
158
+ res[:query]['_p'].first.should == 'truman'
159
+ res[:query]['_n'].first.should == 'harry'
160
+ res[:query]['_t'].first.should == Time.now.to_i.to_s
161
+ end
162
+ end
163
+ context "reading from files" do
164
+ before do
165
+ Dir.glob(__('log','*')).each do |file|
166
+ FileUtils.rm file
167
+ end
168
+ KM.reset
169
+ end
170
+ it "should run fine even though there's no server to connect to" do
171
+ KM::init 'KM_OTHER', :log_dir => __('log'), :host => '127.0.0.1:9291', :to_stderr => false
172
+ KM::identify 'bob'
173
+ KM::record 'My Action' # records an action with no action-specific properties;
174
+ Helper.accept(:history).size.should == 0
175
+ File.exists?(__('log/kissmetrics_production_query.log')).should == true
176
+ File.exists?(__('log/kissmetrics_production_error.log')).should == true
177
+ end
178
+
179
+ it "should escape @ properly" do
180
+ KM::init 'KM_OTHER', :log_dir => __('log'), :host => '127.0.0.1:9292', :to_stderr => false, :use_cron => true
181
+ KM::identify 'bob'
182
+ KM::record 'prop_with_@_in' # records an action with no action-specific properties;
183
+ IO.readlines(KM::log_name(:query)).join.should_not contain_string('@')
184
+ end
185
+ end
186
+ end
data/spec/log/.hold ADDED
File without changes
data/spec/setup.rb ADDED
@@ -0,0 +1,78 @@
1
+ require 'ap'
2
+ require 'km'
3
+ require 'fileutils'
4
+ require 'accept'
5
+
6
+ class KM
7
+ class << self
8
+ public :log_name, :reset, :log
9
+ end
10
+ end
11
+
12
+ def __(*args)
13
+ file_this_included_from = caller.first.split(":").first
14
+ app_root = File.expand_path(File.dirname(file_this_included_from))
15
+ args = [app_root]+args
16
+ File.expand_path(File.join(args))
17
+ end
18
+
19
+ class Helper
20
+ def self.accept(cmd)
21
+ c = TCPSocket.new('localhost', 9292)
22
+ c.puts cmd.to_s
23
+ return JSON.parse(c.read) rescue nil
24
+ end
25
+ def self.history
26
+ accept :history
27
+ end
28
+ def self.clear
29
+ accept :clear
30
+ end
31
+ def self.exit
32
+ accept :exit
33
+ end
34
+ end
35
+ class String
36
+ def sort
37
+ self.split('').sort.join('')
38
+ end
39
+ def sort!
40
+ replace(self.sort)
41
+ end
42
+ end
43
+
44
+ RSpec::Matchers.define :have_query_string do |expected|
45
+ match do |value|
46
+ expected.sort == value.sort
47
+ end
48
+
49
+ failure_message_for_should do |value|
50
+ "expected #{value.inspect} to match #{expected.inspect}"
51
+ end
52
+ end
53
+ #======================================#
54
+ #= contain_string =#
55
+ #======================================#
56
+ # Check if a string has another string. Usage:
57
+ # some_string.should contain("my string")
58
+ RSpec::Matchers.define :contain_string do |needle|
59
+ match do |haystack|
60
+ haystack.index(needle) ? true : false
61
+ end
62
+ end
63
+
64
+ class Hash
65
+ def indifferent
66
+ Hash.new { |hash,key| hash[key.to_s] if key.class == Symbol }.merge(self)
67
+ end
68
+ end
69
+
70
+ def write_log(type, content)
71
+ KM.instance_eval { @log_dir = __('log') }
72
+ log_name = KM.send :log_name, type
73
+ File.open(log_name, 'w+') do |fh|
74
+ fh.puts content
75
+ end
76
+ end
77
+
78
+ accept = Accept.new
data/spec/watchr.rb ADDED
@@ -0,0 +1,3 @@
1
+ watch('spec/.*spec\.rb') { |md| system("bundle exec rspec --color #{md[0]}") }
2
+ watch('lib/km\.rb') { |md| system("bundle exec rake spec") }
3
+ watch('lib/km/saas\.rb') { |md| system("bundle exec rspec --color spec/km_saas_spec.rb") }
metadata ADDED
@@ -0,0 +1,224 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: km
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 1
8
+ - 0
9
+ version: 1.1.0
10
+ platform: ruby
11
+ authors:
12
+ - KISSmetrics
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-08 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bundler
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 0
31
+ - 0
32
+ version: 1.0.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 2
45
+ - 4
46
+ - 0
47
+ version: 2.4.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: awesome_print
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ type: :development
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: watchr
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ type: :development
88
+ version_requirements: *id005
89
+ - !ruby/object:Gem::Dependency
90
+ name: json
91
+ prerelease: false
92
+ requirement: &id006 !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ type: :development
101
+ version_requirements: *id006
102
+ description: KISSmetrics ruby API gem
103
+ email:
104
+ - support@kissmetrics.com
105
+ executables:
106
+ - km_send
107
+ extensions: []
108
+
109
+ extra_rdoc_files: []
110
+
111
+ files:
112
+ - .gitignore
113
+ - CHANGELOG
114
+ - Gemfile
115
+ - Gemfile.lock
116
+ - README.rdoc
117
+ - Rakefile
118
+ - bin/km_send
119
+ - doc/Accept.html
120
+ - doc/Gemfile.html
121
+ - doc/Hash.html
122
+ - doc/Helper.html
123
+ - doc/KM.html
124
+ - doc/KM/IdentError.html
125
+ - doc/KM/InitError.html
126
+ - doc/KM/SaaS.html
127
+ - doc/KMError.html
128
+ - doc/Object.html
129
+ - doc/README_rdoc.html
130
+ - doc/Rakefile.html
131
+ - doc/String.html
132
+ - doc/bin/km_send.html
133
+ - doc/created.rid
134
+ - doc/images/brick.png
135
+ - doc/images/brick_link.png
136
+ - doc/images/bug.png
137
+ - doc/images/bullet_black.png
138
+ - doc/images/bullet_toggle_minus.png
139
+ - doc/images/bullet_toggle_plus.png
140
+ - doc/images/date.png
141
+ - doc/images/find.png
142
+ - doc/images/loadingAnimation.gif
143
+ - doc/images/macFFBgHack.png
144
+ - doc/images/package.png
145
+ - doc/images/page_green.png
146
+ - doc/images/page_white_text.png
147
+ - doc/images/page_white_width.png
148
+ - doc/images/plugin.png
149
+ - doc/images/ruby.png
150
+ - doc/images/tag_green.png
151
+ - doc/images/wrench.png
152
+ - doc/images/wrench_orange.png
153
+ - doc/images/zoom.png
154
+ - doc/index.html
155
+ - doc/js/darkfish.js
156
+ - doc/js/jquery.js
157
+ - doc/js/quicksearch.js
158
+ - doc/js/thickbox-compressed.js
159
+ - doc/lib/km/saas_rb.html
160
+ - doc/lib/km/version_rb.html
161
+ - doc/lib/km_rb.html
162
+ - doc/rdoc.css
163
+ - doc/spec/accept_rb.html
164
+ - doc/spec/km_old_rb.html
165
+ - doc/spec/km_saas_spec_rb.html
166
+ - doc/spec/km_send_spec_rb.html
167
+ - doc/spec/km_spec_rb.html
168
+ - doc/spec/setup_rb.html
169
+ - doc/spec/watchr_rb.html
170
+ - km.gemspec
171
+ - lib/km.rb
172
+ - lib/km/saas.rb
173
+ - lib/km/version.rb
174
+ - spec/accept.rb
175
+ - spec/km_old.rb
176
+ - spec/km_saas_spec.rb
177
+ - spec/km_send_spec.rb
178
+ - spec/km_spec.rb
179
+ - spec/log/.hold
180
+ - spec/setup.rb
181
+ - spec/watchr.rb
182
+ has_rdoc: true
183
+ homepage: http://rubygems.org/gems/km
184
+ licenses: []
185
+
186
+ post_install_message:
187
+ rdoc_options: []
188
+
189
+ require_paths:
190
+ - lib
191
+ required_ruby_version: !ruby/object:Gem::Requirement
192
+ none: false
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ segments:
197
+ - 0
198
+ version: "0"
199
+ required_rubygems_version: !ruby/object:Gem::Requirement
200
+ none: false
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ segments:
205
+ - 1
206
+ - 3
207
+ - 6
208
+ version: 1.3.6
209
+ requirements: []
210
+
211
+ rubyforge_project: kissmetrics
212
+ rubygems_version: 1.3.7
213
+ signing_key:
214
+ specification_version: 3
215
+ summary: KISSmetrics ruby API gem
216
+ test_files:
217
+ - spec/accept.rb
218
+ - spec/km_old.rb
219
+ - spec/km_saas_spec.rb
220
+ - spec/km_send_spec.rb
221
+ - spec/km_spec.rb
222
+ - spec/log/.hold
223
+ - spec/setup.rb
224
+ - spec/watchr.rb