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