appstats 0.19.7 → 0.20.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/Gemfile.lock +1 -1
- data/db/migrations/20110330171745_create_appstats_action_contexts.rb +14 -0
- data/db/schema.rb +9 -1
- data/lib/appstats.rb +2 -0
- data/lib/appstats/action_context_key.rb +23 -0
- data/lib/appstats/appstats_query.rb +92 -0
- data/lib/appstats/parser.rb +18 -4
- data/lib/appstats/version.rb +1 -1
- data/lib/daemons/appstats_log_collector.rb +1 -0
- data/spec/action_context_key_spec.rb +81 -0
- data/spec/appstats_query_spec.rb +144 -0
- data/spec/entry_spec.rb +8 -8
- data/spec/logger_spec.rb +22 -22
- data/spec/parser_spec.rb +173 -137
- metadata +11 -4
data/Gemfile.lock
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateAppstatsActionContexts < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :appstats_action_context_keys do |t|
|
4
|
+
t.string :action_name
|
5
|
+
t.string :context_key
|
6
|
+
t.string :status
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
drop_table :appstats_action_context_keys
|
13
|
+
end
|
14
|
+
end
|
data/db/schema.rb
CHANGED
@@ -10,7 +10,15 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended to check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(:version =>
|
13
|
+
ActiveRecord::Schema.define(:version => 20110330171745) do
|
14
|
+
|
15
|
+
create_table "appstats_action_context_keys", :force => true do |t|
|
16
|
+
t.string "action_name"
|
17
|
+
t.string "context_key"
|
18
|
+
t.string "status"
|
19
|
+
t.datetime "created_at"
|
20
|
+
t.datetime "updated_at"
|
21
|
+
end
|
14
22
|
|
15
23
|
create_table "appstats_actions", :force => true do |t|
|
16
24
|
t.string "name"
|
data/lib/appstats.rb
CHANGED
@@ -7,6 +7,7 @@ require "#{File.dirname(__FILE__)}/appstats/entry_date"
|
|
7
7
|
require "#{File.dirname(__FILE__)}/appstats/date_range"
|
8
8
|
require "#{File.dirname(__FILE__)}/appstats/action"
|
9
9
|
require "#{File.dirname(__FILE__)}/appstats/context"
|
10
|
+
require "#{File.dirname(__FILE__)}/appstats/action_context_key"
|
10
11
|
require "#{File.dirname(__FILE__)}/appstats/tasks"
|
11
12
|
require "#{File.dirname(__FILE__)}/appstats/logger"
|
12
13
|
require "#{File.dirname(__FILE__)}/appstats/log_collector"
|
@@ -18,6 +19,7 @@ require "#{File.dirname(__FILE__)}/appstats/result_job"
|
|
18
19
|
require "#{File.dirname(__FILE__)}/appstats/host"
|
19
20
|
require "#{File.dirname(__FILE__)}/appstats/friendly_timer"
|
20
21
|
require "#{File.dirname(__FILE__)}/appstats/context_key"
|
22
|
+
require "#{File.dirname(__FILE__)}/appstats/appstats_query"
|
21
23
|
require "#{File.dirname(__FILE__)}/appstats/context_value"
|
22
24
|
require "#{File.dirname(__FILE__)}/appstats/test_object"
|
23
25
|
require "#{File.dirname(__FILE__)}/appstats/test_query"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module Appstats
|
3
|
+
class ActionContextKey < ActiveRecord::Base
|
4
|
+
set_table_name "appstats_action_context_keys"
|
5
|
+
|
6
|
+
attr_accessible :action_name, :context_key, :status
|
7
|
+
|
8
|
+
def self.update_action_context_keys
|
9
|
+
sql = "select action,context_key,count(*) as num
|
10
|
+
from appstats_entries
|
11
|
+
inner join appstats_contexts on appstats_contexts.appstats_entry_id = appstats_entries.id
|
12
|
+
where (action,context_key) not in (select action_name, context_key from appstats_action_context_keys)
|
13
|
+
group by action,context_key"
|
14
|
+
count = 0
|
15
|
+
ActiveRecord::Base.connection.execute(sql).each do |row|
|
16
|
+
Appstats::ActionContextKey.create(:action_name => row[0], :context_key => row[1], :status => 'derived')
|
17
|
+
count += 1
|
18
|
+
end
|
19
|
+
count
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class AppstatsQuery
|
2
|
+
|
3
|
+
attr_accessor :query
|
4
|
+
|
5
|
+
@@default_query = "select 0 as num"
|
6
|
+
|
7
|
+
@@action_to_available_contexts =
|
8
|
+
{
|
9
|
+
"appstats_queries" => [ "action", "contexts", "group_by" ],
|
10
|
+
"bomb" => []
|
11
|
+
}
|
12
|
+
|
13
|
+
def query_to_sql
|
14
|
+
return @@default_query if query.nil?
|
15
|
+
query.query_to_sql
|
16
|
+
end
|
17
|
+
|
18
|
+
def group_query_to_sql
|
19
|
+
return nil if query.nil?
|
20
|
+
query.group_query_to_sql
|
21
|
+
end
|
22
|
+
|
23
|
+
def process_query
|
24
|
+
return if query.nil?
|
25
|
+
query.query_to_sql = @@default_query
|
26
|
+
query.group_query_to_sql = nil
|
27
|
+
return if query.action.blank?
|
28
|
+
|
29
|
+
action = query.action.pluralize.downcase
|
30
|
+
case action
|
31
|
+
when "appstats_queries"
|
32
|
+
count_filter = "COUNT(*)"
|
33
|
+
query.query_to_sql = "select #{count_filter} as num from appstats_results#{build_where_clause}"
|
34
|
+
when "bombs"
|
35
|
+
query.query_to_sql = "invalid sql"
|
36
|
+
end
|
37
|
+
query.group_query_to_sql = query.query_to_sql.sub("#{count_filter} as num","#{context_key_filter_name(action)} as context_key_filter, #{context_value_filter_name(action)} as context_value_filter, COUNT(*) as num") + " group by context_value_filter" unless query.group_by.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
def run
|
41
|
+
query.run
|
42
|
+
end
|
43
|
+
|
44
|
+
def db_connection
|
45
|
+
ActiveRecord::Base.connection
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.available_action?(action)
|
49
|
+
return false if action.blank?
|
50
|
+
return @@action_to_available_contexts.keys.include?(action.downcase.pluralize)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def build_where_clause
|
56
|
+
where_clause = ""
|
57
|
+
action = query.action.pluralize.downcase
|
58
|
+
available_contexts = @@action_to_available_contexts[action]
|
59
|
+
status = :context
|
60
|
+
query.parsed_contexts.each do |lookup|
|
61
|
+
next if status == :context && lookup.kind_of?(String)
|
62
|
+
next if status == :join && !lookup.kind_of?(String)
|
63
|
+
next if status == :context && (lookup[:context_value].nil? || !available_contexts.include?(lookup[:context_key]))
|
64
|
+
|
65
|
+
where_clause = " where" if where_clause.blank?
|
66
|
+
if lookup.kind_of?(String)
|
67
|
+
where_clause += " #{lookup}"
|
68
|
+
status = :context
|
69
|
+
elsif !lookup[:context_value].nil? && available_contexts.include?(lookup[:context_key])
|
70
|
+
where_clause += " #{database_column(action,lookup[:context_key])} #{lookup[:comparator]} '#{Appstats::Query.sqlclean(lookup[:context_value])}'"
|
71
|
+
status = :join
|
72
|
+
end
|
73
|
+
end
|
74
|
+
where_clause
|
75
|
+
end
|
76
|
+
|
77
|
+
def context_key_filter_name(action)
|
78
|
+
"'" + query.group_by.join(",") + "'"
|
79
|
+
end
|
80
|
+
|
81
|
+
def context_value_filter_name(action)
|
82
|
+
database_names = query.group_by.collect do |name|
|
83
|
+
database_column(action,name)
|
84
|
+
end
|
85
|
+
"concat(ifnull("+ database_names.join(",'--'),',',ifnull(") +",'--'))"
|
86
|
+
end
|
87
|
+
|
88
|
+
def database_column(action,name)
|
89
|
+
name
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/lib/appstats/parser.rb
CHANGED
@@ -73,13 +73,27 @@ module Appstats
|
|
73
73
|
true
|
74
74
|
end
|
75
75
|
|
76
|
+
def self.alpha?(raw_input)
|
77
|
+
return false if raw_input.nil?
|
78
|
+
!raw_input.match(/^[A-Za-z]+$/i).nil?
|
79
|
+
end
|
80
|
+
|
76
81
|
def self.parse_constant(current_text,constant)
|
77
82
|
answer = [nil,nil]
|
78
83
|
return answer if current_text.blank? || constant.nil?
|
79
84
|
current_text.strip!
|
80
|
-
|
85
|
+
|
86
|
+
remaining_text_index = -1
|
87
|
+
if alpha?(constant)
|
88
|
+
m = current_text.match(/^(#{constant})(\s|$)(.*)$/im)
|
89
|
+
remaining_text_index = 3
|
90
|
+
else
|
91
|
+
m = current_text.match(/^(#{constant})(.*)$/im)
|
92
|
+
remaining_text_index = 2
|
93
|
+
end
|
94
|
+
|
81
95
|
answer[0] = m[1] unless m.nil?
|
82
|
-
answer[1] = m.nil? ? current_text : m[
|
96
|
+
answer[1] = m.nil? ? current_text : m[remaining_text_index]
|
83
97
|
clean_parsed_word(answer)
|
84
98
|
end
|
85
99
|
|
@@ -186,7 +200,7 @@ module Appstats
|
|
186
200
|
current_token.gsub!(")",'\)')
|
187
201
|
current_token.gsub!("|",'\|')
|
188
202
|
@tokenize_no_spaces<< current_token
|
189
|
-
current_token = "\\s+#{current_token}" unless current_token.match(/.*[a-z].*/i).nil?
|
203
|
+
current_token = "\\s+#{current_token}(\\s|$)" unless current_token.match(/.*[a-z].*/i).nil?
|
190
204
|
@tokenize<< current_token
|
191
205
|
end
|
192
206
|
@tokenize_regex_no_spaces = @tokenize_no_spaces.join("|")
|
@@ -209,7 +223,7 @@ module Appstats
|
|
209
223
|
current_rule = rule.upcase
|
210
224
|
current_rule_no_spaces = current_rule
|
211
225
|
@constants_no_spaces<< current_rule_no_spaces
|
212
|
-
current_rule = "\\s+#{current_rule}" unless current_rule.match(/.*[a-z].*/i).nil?
|
226
|
+
current_rule = "\\s+#{current_rule}(\\s|$)" unless current_rule.match(/.*[a-z].*/i).nil?
|
213
227
|
@constants<< current_rule
|
214
228
|
previous_stop_on = :constant
|
215
229
|
end
|
data/lib/appstats/version.rb
CHANGED
@@ -63,6 +63,7 @@ while($running) do
|
|
63
63
|
Appstats::Host.update_hosts
|
64
64
|
Appstats::ContextKey.update_context_keys
|
65
65
|
Appstats::ContextValue.update_context_values
|
66
|
+
Appstats::ActionContextKey.update_action_context_keys
|
66
67
|
Appstats::LogCollector.remove_remote_files(appstats_config["remote_servers"])
|
67
68
|
ActiveRecord::Base.connection.disconnect!
|
68
69
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Appstats
|
4
|
+
describe ActionContextKey do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
Appstats::Entry.delete_all
|
8
|
+
Appstats::Context.delete_all
|
9
|
+
Appstats::ActionContextKey.delete_all
|
10
|
+
@action = Appstats::ActionContextKey.new
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
describe "#initialize" do
|
16
|
+
|
17
|
+
it "should set action_name to nil" do
|
18
|
+
@action.action_name.should == nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should set context_key to nil" do
|
22
|
+
@action.context_key.should == nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set status to nil" do
|
26
|
+
@action.status.should == nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should set on constructor" do
|
30
|
+
action = Appstats::ActionContextKey.new(:action_name => 'a', :context_key => 'b', :status => 'c')
|
31
|
+
action.action_name.should == 'a'
|
32
|
+
action.context_key.should == 'b'
|
33
|
+
action.status.should == 'c'
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#update_action_context_keys" do
|
39
|
+
|
40
|
+
it "should do nothing if no events" do
|
41
|
+
Appstats::ActionContextKey.update_action_context_keys.should == 0
|
42
|
+
Appstats::ActionContextKey.count.should == 0
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should ignore actions without any contexts" do
|
46
|
+
Appstats::Entry.create_from_logger('a')
|
47
|
+
Appstats::ActionContextKey.update_action_context_keys.should == 0
|
48
|
+
Appstats::ActionContextKey.count.should == 0
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should add entry action / context names" do
|
53
|
+
Appstats::Entry.create_from_logger('a',:blah => "x")
|
54
|
+
Appstats::ActionContextKey.update_action_context_keys.should == 1
|
55
|
+
Appstats::ActionContextKey.count.should == 1
|
56
|
+
|
57
|
+
action = Appstats::ActionContextKey.last
|
58
|
+
action.action_name = 'a'
|
59
|
+
action.context_key = 'blah'
|
60
|
+
action.status = 'derived'
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should ignore existing entries action / context names" do
|
64
|
+
Appstats::Entry.create_from_logger('a',:blah => "x")
|
65
|
+
Appstats::ActionContextKey.update_action_context_keys.should == 1
|
66
|
+
Appstats::ActionContextKey.update_action_context_keys.should == 0
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should ignore duplicates" do
|
70
|
+
Appstats::Entry.create_from_logger('a',:blah => "x")
|
71
|
+
Appstats::Entry.create_from_logger('a',:blah => "y")
|
72
|
+
Appstats::ActionContextKey.update_action_context_keys.should == 1
|
73
|
+
Appstats::ActionContextKey.count.should == 1
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Appstats
|
4
|
+
|
5
|
+
describe AppstatsQuery do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Time.stub!(:now).and_return(Time.parse('2010-09-21 23:15:20'))
|
9
|
+
@appstats_query = AppstatsQuery.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#available_action?" do
|
13
|
+
|
14
|
+
it "should be false for nil" do
|
15
|
+
AppstatsQuery.available_action?(nil).should == false
|
16
|
+
AppstatsQuery.available_action?("").should == false
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be false for blah" do
|
20
|
+
AppstatsQuery.available_action?("blah").should == false
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be true for appstats_queries" do
|
24
|
+
AppstatsQuery.available_action?("appstats_queries").should == true
|
25
|
+
AppstatsQuery.available_action?("Appstats_queries").should == true
|
26
|
+
AppstatsQuery.available_action?("appstats_query").should == true
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#query_to_sql" do
|
32
|
+
|
33
|
+
it "should be nil if no query" do
|
34
|
+
@appstats_query.query_to_sql.should == "select 0 as num"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should be based on query" do
|
38
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_queries")
|
39
|
+
@appstats_query.query_to_sql.should == @appstats_query.query.query_to_sql
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#group_query_to_sql" do
|
45
|
+
|
46
|
+
it "should be nil if no query" do
|
47
|
+
@appstats_query.group_query_to_sql.should == nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be based on query" do
|
51
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_queries")
|
52
|
+
@appstats_query.group_query_to_sql.should == @appstats_query.query.group_query_to_sql
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#process_query" do
|
58
|
+
|
59
|
+
it "should support nil query" do
|
60
|
+
@appstats_query.process_query
|
61
|
+
@appstats_query.query_to_sql.should == "select 0 as num"
|
62
|
+
@appstats_query.group_query_to_sql.should == nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be case insensitive on action" do
|
66
|
+
@appstats_query.query = Appstats::Query.new(:query => "# Appstats_Queries", :query_type => "Appstats::AppstatsQuery")
|
67
|
+
@appstats_query.process_query
|
68
|
+
@appstats_query.query_to_sql.should == "select COUNT(*) as num from appstats_results"
|
69
|
+
|
70
|
+
@appstats_query.query = Appstats::Query.new(:query => "# aPpstats_Queries", :query_type => "Appstats::AppstatsQuery")
|
71
|
+
@appstats_query.process_query
|
72
|
+
@appstats_query.query_to_sql.should == "select COUNT(*) as num from appstats_results"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should support singular names" do
|
76
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_query", :query_type => "Appstats::AppstatsQuery")
|
77
|
+
@appstats_query.process_query
|
78
|
+
@appstats_query.query_to_sql.should == "select COUNT(*) as num from appstats_results"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should handle nil actions" do
|
82
|
+
@appstats_query.query = Appstats::Query.new(:query => "", :query_type => "Appstats::AppstatsQuery")
|
83
|
+
@appstats_query.process_query
|
84
|
+
@appstats_query.query_to_sql.should == "select 0 as num"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should call query.run" do
|
88
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_queries", :query_type => "Appstats::AppstatsQuery")
|
89
|
+
@appstats_query.query.stub!(:run).and_return("call-worked")
|
90
|
+
@appstats_query.run.should == "call-worked"
|
91
|
+
end
|
92
|
+
|
93
|
+
# THIS IS A SLOW TEST ONLY TO BE RUN IF THINGS START ACTING STRANGE
|
94
|
+
it "should actually execute code properly" do
|
95
|
+
Result.create
|
96
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_queries", :query_type => "Appstats::AppstatsQuery")
|
97
|
+
@appstats_query.run.count.should > 0
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "# appstats_queries" do
|
101
|
+
|
102
|
+
it "should support #appstats_queries" do
|
103
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_queries", :query_type => "Appstats::AppstatsQuery")
|
104
|
+
@appstats_query.process_query
|
105
|
+
@appstats_query.query_to_sql.should == "select COUNT(*) as num from appstats_results"
|
106
|
+
@appstats_query.group_query_to_sql.should == nil
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should support where clause for action, contexts, group_by" do
|
110
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_queries where action = abc AND contexts = 'def' || group_by like 'hik'", :query_type => "Appstats::AppstatsQuery")
|
111
|
+
@appstats_query.process_query
|
112
|
+
@appstats_query.query_to_sql.should == "select COUNT(*) as num from appstats_results where action = 'abc' AND contexts = 'def' or group_by like 'hik'"
|
113
|
+
@appstats_query.group_query_to_sql.should == nil
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should support group by action, contexts, group_by" do
|
117
|
+
@appstats_query.query = Appstats::Query.new(:query => "# appstats_queries group by action, contexts, group_by", :query_type => "Appstats::AppstatsQuery")
|
118
|
+
@appstats_query.process_query
|
119
|
+
@appstats_query.query_to_sql.should == "select COUNT(*) as num from appstats_results"
|
120
|
+
@appstats_query.group_query_to_sql.should == "select 'action,contexts,group_by' as context_key_filter, concat(ifnull(action,'--'),',',ifnull(contexts,'--'),',',ifnull(group_by,'--')) as context_value_filter, COUNT(*) as num from appstats_results group by context_value_filter"
|
121
|
+
end
|
122
|
+
|
123
|
+
# it "should support group by media,network" do
|
124
|
+
# @appstats_query.query = Appstats::Query.new(:query => "# buildings group by media, network", :query_type => "Appstats::AppstatsQuery")
|
125
|
+
# @appstats_query.process_query
|
126
|
+
# @appstats_query.query_to_sql.should == "select COUNT(DISTINCT operator_accesses.id) as num from operator_accesses left join physical_addresses on physical_addresses.id = operator_accesses.physical_address_id left join operator_networks on operator_networks.id = operator_accesses.operator_network_id left join service_providers on service_providers.id = operator_networks.service_provider_id"
|
127
|
+
# @appstats_query.group_query_to_sql.should == "select 'media,network' as context_key_filter, concat(media_types.name,',',operator_networks.name) as context_value_filter, COUNT(*) as num from operator_accesses left join physical_addresses on physical_addresses.id = operator_accesses.physical_address_id left join operator_networks on operator_networks.id = operator_accesses.operator_network_id left join service_providers on service_providers.id = operator_networks.service_provider_id group by context_value_filter"
|
128
|
+
# end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#db_connection" do
|
134
|
+
|
135
|
+
it "should use the extract_env" do
|
136
|
+
@appstats_query.query = Appstats::Query.new(:query => "# blahs on blah")
|
137
|
+
@appstats_query.db_connection.should == ActiveRecord::Base.connection
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
data/spec/entry_spec.rb
CHANGED
@@ -193,18 +193,18 @@ module Appstats
|
|
193
193
|
end
|
194
194
|
|
195
195
|
it "should understand an entry without contexts" do
|
196
|
-
entry = Entry.create_from_logger_string("0.
|
196
|
+
entry = Entry.create_from_logger_string("0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
|
197
197
|
Entry.count.should == @before_count + 1
|
198
198
|
entry.action.should == "address_search"
|
199
|
-
entry.raw_entry.should == "0.
|
199
|
+
entry.raw_entry.should == "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
|
200
200
|
entry.occurred_at.should == Time.parse("2010-09-21 23:15:20")
|
201
201
|
end
|
202
202
|
|
203
203
|
it "should understand contexts" do
|
204
|
-
entry = Entry.create_from_logger_string("0.
|
204
|
+
entry = Entry.create_from_logger_string("0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
|
205
205
|
Entry.count.should == @before_count + 1
|
206
206
|
entry.action.should == "address_filter"
|
207
|
-
entry.raw_entry.should == "0.
|
207
|
+
entry.raw_entry.should == "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
|
208
208
|
entry.occurred_at.should == Time.parse("2010-09-21 23:15:20")
|
209
209
|
entry.contexts.size.should == 2
|
210
210
|
entry.contexts[0].context_key = "app_name"
|
@@ -214,10 +214,10 @@ module Appstats
|
|
214
214
|
end
|
215
215
|
|
216
216
|
it "should handle 'action' as a context" do
|
217
|
-
entry = Entry.create_from_logger_string('0.
|
217
|
+
entry = Entry.create_from_logger_string('0.20.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : action=save_ovcen : app_name=cdb')
|
218
218
|
Entry.count.should == @before_count + 1
|
219
219
|
entry.action.should == "page-view"
|
220
|
-
entry.raw_entry.should == "0.
|
220
|
+
entry.raw_entry.should == "0.20.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : action=save_ovcen : app_name=cdb"
|
221
221
|
entry.occurred_at.should == Time.parse("2011-02-24 12:59:57")
|
222
222
|
entry.contexts.size.should == 2
|
223
223
|
entry.contexts[0].context_key = "action"
|
@@ -228,10 +228,10 @@ module Appstats
|
|
228
228
|
end
|
229
229
|
|
230
230
|
it "should handle multiple of the same 'context'" do
|
231
|
-
entry = Entry.create_from_logger_string('0.
|
231
|
+
entry = Entry.create_from_logger_string('0.20.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : app_name=market : app_name=cdb')
|
232
232
|
Entry.count.should == @before_count + 1
|
233
233
|
entry.action.should == "page-view"
|
234
|
-
entry.raw_entry.should == "0.
|
234
|
+
entry.raw_entry.should == "0.20.0 setup[:,=,-n] 2011-02-24 12:59:57 action=page-view : app_name=market : app_name=cdb"
|
235
235
|
entry.occurred_at.should == Time.parse("2011-02-24 12:59:57")
|
236
236
|
entry.contexts.size.should == 2
|
237
237
|
entry.contexts[0].context_key = "app_name"
|
data/spec/logger_spec.rb
CHANGED
@@ -122,12 +122,12 @@ module Appstats
|
|
122
122
|
|
123
123
|
it "should accept numbers" do
|
124
124
|
Appstats::Logger.entry(5, :blah => 6)
|
125
|
-
Appstats::Logger.raw_read.should == ["0.
|
125
|
+
Appstats::Logger.raw_read.should == ["0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=5 : blah=6"]
|
126
126
|
end
|
127
127
|
|
128
128
|
it "should accept arrays" do
|
129
129
|
Appstats::Logger.entry('search', :provider => [ 'one', 'two' ])
|
130
|
-
Appstats::Logger.raw_read.should == ["0.
|
130
|
+
Appstats::Logger.raw_read.should == ["0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=search : provider=one : provider=two"]
|
131
131
|
end
|
132
132
|
|
133
133
|
|
@@ -137,7 +137,7 @@ module Appstats
|
|
137
137
|
|
138
138
|
it "should look similar to regular entry" do
|
139
139
|
Appstats::Logger.exception_entry(RuntimeError.new("blah"),:on => "login")
|
140
|
-
Appstats::Logger.raw_read.should == ["0.
|
140
|
+
Appstats::Logger.raw_read.should == ["0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=appstats-exception : error=blah : on=login"]
|
141
141
|
end
|
142
142
|
|
143
143
|
end
|
@@ -154,47 +154,47 @@ module Appstats
|
|
154
154
|
|
155
155
|
it "should handle a statistics entry" do
|
156
156
|
expected = { :action => "address_search", :timestamp => "2010-09-21 23:15:20" }
|
157
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
157
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
|
158
158
|
actual.should == expected
|
159
159
|
end
|
160
160
|
|
161
161
|
it "should handle contexts" do
|
162
162
|
expected = { :action => "address_filter", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
|
163
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
163
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
|
164
164
|
actual.should == expected
|
165
165
|
end
|
166
166
|
|
167
167
|
it "should handle multiple actions" do
|
168
168
|
expected = { :action => ["address_filter", "blah"], :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
|
169
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
169
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : action=blah : app_name=Market : server=Live")
|
170
170
|
actual.should == expected
|
171
171
|
end
|
172
172
|
|
173
173
|
it "should handle multiple of same context" do
|
174
174
|
expected = { :action => "address_filter", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => ['Sin','Market'] }
|
175
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
175
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Sin : app_name=Market : server=Live")
|
176
176
|
actual.should == expected
|
177
177
|
end
|
178
178
|
|
179
179
|
it "should handle no actions" do
|
180
180
|
expected = { :action => "UNKNOWN_ACTION", :timestamp => "2010-09-21 23:15:20", :server => "Live", :app_name => 'Market' }
|
181
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
181
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 app_name=Market : server=Live")
|
182
182
|
actual.should == expected
|
183
183
|
end
|
184
184
|
|
185
185
|
it "should handle actions with the delimiter (and change the delimiter)" do
|
186
186
|
expected = { :action => "address:=search-n", :timestamp => "2010-09-21 23:15:20" }
|
187
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
187
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n")
|
188
188
|
actual.should == expected
|
189
189
|
|
190
190
|
expected = { :action => "address::search==--n", :timestamp => "2010-09-21 23:15:20" }
|
191
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
191
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n")
|
192
192
|
actual.should == expected
|
193
193
|
end
|
194
194
|
|
195
195
|
it "should handle contexts with the delimiter (and change the delimiter)" do
|
196
196
|
expected = { :action => "address", :timestamp => "2010-09-21 23:15:20", :server => "market:eval=-n" }
|
197
|
-
actual = Appstats::Logger.entry_to_hash("0.
|
197
|
+
actual = Appstats::Logger.entry_to_hash("0.20.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n")
|
198
198
|
actual.should == expected
|
199
199
|
end
|
200
200
|
|
@@ -203,66 +203,66 @@ module Appstats
|
|
203
203
|
describe "#entry_to_s" do
|
204
204
|
|
205
205
|
it "should handle a statistics entry" do
|
206
|
-
expected = "0.
|
206
|
+
expected = "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
|
207
207
|
actual = Appstats::Logger.entry_to_s("address_search")
|
208
208
|
actual.should == expected
|
209
209
|
end
|
210
210
|
|
211
211
|
it "should handle numbers" do
|
212
|
-
expected = "0.
|
212
|
+
expected = "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=1 : note=2.2"
|
213
213
|
actual = Appstats::Logger.entry_to_s(1,:note => 2.2)
|
214
214
|
actual.should == expected
|
215
215
|
end
|
216
216
|
|
217
217
|
it "should handle default contexts" do
|
218
218
|
Appstats::Logger.default_contexts[:app_name] = "market"
|
219
|
-
expected = "0.
|
219
|
+
expected = "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : app_name=market"
|
220
220
|
actual = Appstats::Logger.entry_to_s("address_search")
|
221
221
|
actual.should == expected
|
222
222
|
end
|
223
223
|
|
224
224
|
it "should handle contexts (and sort them by symbol)" do
|
225
|
-
expected = "0.
|
225
|
+
expected = "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
|
226
226
|
actual = Appstats::Logger.entry_to_s("address_filter", { :server => "Live", :app_name => 'Market' })
|
227
227
|
actual.should == expected
|
228
228
|
end
|
229
229
|
|
230
230
|
it "should handle actions with the delimiter (and change the delimiter)" do
|
231
|
-
expected = "0.
|
231
|
+
expected = "0.20.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=search-n"
|
232
232
|
actual = Appstats::Logger.entry_to_s("address:=search-n")
|
233
233
|
actual.should == expected
|
234
234
|
|
235
|
-
expected = "0.
|
235
|
+
expected = "0.20.0 setup[:::,===,---n] 2010-09-21 23:15:20 action===address::search==--n"
|
236
236
|
actual = Appstats::Logger.entry_to_s("address::search==--n")
|
237
237
|
actual.should == expected
|
238
238
|
end
|
239
239
|
|
240
240
|
it "should handle contexts with the delimiter (and change the delimiter)" do
|
241
|
-
expected = "0.
|
241
|
+
expected = "0.20.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address :: server==market:eval=-n"
|
242
242
|
actual = Appstats::Logger.entry_to_s("address", :server => 'market:eval=-n')
|
243
243
|
actual.should == expected
|
244
244
|
end
|
245
245
|
|
246
246
|
it "should ignore spaces" do
|
247
|
-
expected = "0.
|
247
|
+
expected = "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address search"
|
248
248
|
actual = Appstats::Logger.entry_to_s("address search")
|
249
249
|
actual.should == expected
|
250
250
|
end
|
251
251
|
|
252
252
|
it "should convert newlines in action" do
|
253
|
-
expected = "0.
|
253
|
+
expected = "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_-nsearch"
|
254
254
|
actual = Appstats::Logger.entry_to_s("address_\nsearch")
|
255
255
|
actual.should == expected
|
256
256
|
end
|
257
257
|
|
258
258
|
it "should convert newlines in context" do
|
259
|
-
expected = "0.
|
259
|
+
expected = "0.20.0 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search : blah=some-nlong-nstatement"
|
260
260
|
actual = Appstats::Logger.entry_to_s("address_search",:blah => "some\nlong\nstatement")
|
261
261
|
actual.should == expected
|
262
262
|
end
|
263
263
|
|
264
264
|
it "should convert newlines based on the delimiter" do
|
265
|
-
expected = "0.
|
265
|
+
expected = "0.20.0 setup[::,==,--n] 2010-09-21 23:15:20 action==address:=--nsearch-n"
|
266
266
|
actual = Appstats::Logger.entry_to_s("address:=\nsearch-n")
|
267
267
|
actual.should == expected
|
268
268
|
end
|
data/spec/parser_spec.rb
CHANGED
@@ -8,153 +8,153 @@ module Appstats
|
|
8
8
|
end
|
9
9
|
|
10
10
|
describe("#initialize") do
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
it "should espace tokens as required" do
|
36
|
-
parser = Parser.new(:tokenize => "( ) abc |")
|
37
|
-
parser.tokenize.should == ['\(','\)','\s+ABC','\|']
|
38
|
-
parser.tokenize_regex.should == '\(|\)|\s+ABC|\|'
|
39
|
-
parser.tokenize_no_spaces.should == ['\(','\)','ABC','\|']
|
40
|
-
parser.tokenize_regex_no_spaces.should == '\(|\)|ABC|\|'
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
11
|
+
|
12
|
+
it "should set rules to nil" do
|
13
|
+
@parser.raw_rules.should == nil
|
14
|
+
@parser.raw_tokenize.should == nil
|
15
|
+
@parser.repeating.should == false
|
16
|
+
@parser.tokenize_regex == nil
|
17
|
+
@parser.rules.should == []
|
18
|
+
@parser.tokenize.should == []
|
19
|
+
@parser.constants.should == []
|
20
|
+
@parser.constants_no_spaces.should == []
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should set rules from constructor" do
|
24
|
+
parser = Parser.new(:rules => ":name or :bust", :tokenize => "a bb c", :repeating => true)
|
25
|
+
parser.raw_rules.should == ":name or :bust"
|
26
|
+
parser.raw_tokenize.should == "a bb c"
|
27
|
+
parser.repeating.should == true
|
28
|
+
parser.rules.should == [ { :rule => :name, :stop => :constant }, "OR", { :rule => :bust, :stop => :end} ]
|
29
|
+
parser.tokenize.should == ["\\s+A(\\s|$)","\\s+BB(\\s|$)","\\s+C(\\s|$)"]
|
30
|
+
parser.tokenize_no_spaces.should == ["A","BB","C"]
|
31
|
+
parser.constants.should == ["\\s+OR(\\s|$)"]
|
32
|
+
parser.constants_no_spaces.should == ["OR"]
|
33
|
+
end
|
44
34
|
|
35
|
+
it "should espace tokens as required" do
|
36
|
+
parser = Parser.new(:tokenize => "( ) abc |")
|
37
|
+
parser.tokenize.should == ['\(','\)','\s+ABC(\s|$)','\|']
|
38
|
+
parser.tokenize_regex.should == '\(|\)|\s+ABC(\s|$)|\|'
|
39
|
+
parser.tokenize_no_spaces.should == ['\(','\)','ABC','\|']
|
40
|
+
parser.tokenize_regex_no_spaces.should == '\(|\)|ABC|\|'
|
41
|
+
end
|
45
42
|
|
46
|
-
|
47
|
-
|
48
|
-
it "should end on constant if tokens present" do
|
49
|
-
Parser.new(:rules => ":name", :tokenize => ")").rules.should == [ { :rule => :name, :stop => :end } ]
|
50
|
-
end
|
51
|
-
|
43
|
+
end
|
52
44
|
|
53
|
-
it "should handle one variable" do
|
54
|
-
Parser.new(:rules => ":name").rules.should == [ { :rule => :name, :stop => :end } ]
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should handle many variables" do
|
58
|
-
Parser.new(:rules => ":name :date").rules.should == [ { :rule => :name, :stop => :space }, { :rule => :date, :stop => :end } ]
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should deal with colons" do
|
62
|
-
Parser.new(:rules => ":name : :date").rules.should == [ { :rule => :name, :stop => :constant }, ":", { :rule => :date, :stop => :end } ]
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should deal with constant" do
|
66
|
-
Parser.new(:rules => "blah").rules.should == ["BLAH"]
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should deal with constant and variables" do
|
70
|
-
Parser.new(:rules => ":name blah :date").rules.should == [ { :rule => :name, :stop => :constant }, "BLAH", { :rule => :date, :stop => :end } ]
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should deal with multiple constants and variables" do
|
74
|
-
Parser.new(:rules => ":name blah more blah :date").rules.should == [ { :rule => :name, :stop => :constant }, "BLAH", "MORE", "BLAH", { :rule => :date, :stop => :end } ]
|
75
|
-
end
|
76
45
|
|
77
|
-
|
46
|
+
describe "#rules" do
|
78
47
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
48
|
+
it "should end on constant if tokens present" do
|
49
|
+
Parser.new(:rules => ":name", :tokenize => ")").rules.should == [ { :rule => :name, :stop => :end } ]
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
it "should handle one variable" do
|
54
|
+
Parser.new(:rules => ":name").rules.should == [ { :rule => :name, :stop => :end } ]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should handle many variables" do
|
58
|
+
Parser.new(:rules => ":name :date").rules.should == [ { :rule => :name, :stop => :space }, { :rule => :date, :stop => :end } ]
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should deal with colons" do
|
62
|
+
Parser.new(:rules => ":name : :date").rules.should == [ { :rule => :name, :stop => :constant }, ":", { :rule => :date, :stop => :end } ]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should deal with constant" do
|
66
|
+
Parser.new(:rules => "blah").rules.should == ["BLAH"]
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should deal with constant and variables" do
|
70
|
+
Parser.new(:rules => ":name blah :date").rules.should == [ { :rule => :name, :stop => :constant }, "BLAH", { :rule => :date, :stop => :end } ]
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should deal with multiple constants and variables" do
|
74
|
+
Parser.new(:rules => ":name blah more blah :date").rules.should == [ { :rule => :name, :stop => :constant }, "BLAH", "MORE", "BLAH", { :rule => :date, :stop => :end } ]
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
100
78
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
Parser.new(:rules => ":name : :date").constants_no_spaces.should == [ ":" ]
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should upper case constants" do
|
110
|
-
Parser.new(:rules => "blah").constants_no_spaces.should == ["BLAH"]
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should deal with multiple constants" do
|
114
|
-
Parser.new(:rules => ":name = :blah and :moreblah").constants_no_spaces.should == ["=","AND"]
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
79
|
+
describe "#constants" do
|
80
|
+
|
81
|
+
it "should be empty if only variables" do
|
82
|
+
Parser.new(:rules => ":name :blah").constants.should == [ ]
|
83
|
+
end
|
118
84
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
85
|
+
it "should track all constants" do
|
86
|
+
Parser.new(:rules => ":name : :date").constants.should == [ ":" ]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should upper case constants" do
|
90
|
+
Parser.new(:rules => "blah").constants.should == ["\\s+BLAH(\\s|$)"]
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should deal with multiple constants" do
|
94
|
+
Parser.new(:rules => ":name = :blah and :moreblah").constants.should == ["=","\\s+AND(\\s|$)"]
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#constants_no_spaces" do
|
100
|
+
|
101
|
+
it "should be empty if only variables" do
|
102
|
+
Parser.new(:rules => ":name :blah").constants_no_spaces.should == [ ]
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should track all constants" do
|
106
|
+
Parser.new(:rules => ":name : :date").constants_no_spaces.should == [ ":" ]
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should upper case constants" do
|
110
|
+
Parser.new(:rules => "blah").constants_no_spaces.should == ["BLAH"]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should deal with multiple constants" do
|
114
|
+
Parser.new(:rules => ":name = :blah and :moreblah").constants_no_spaces.should == ["=","AND"]
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
147
118
|
|
148
|
-
|
119
|
+
describe "#parse_constant" do
|
120
|
+
|
121
|
+
it "should handle nil" do
|
122
|
+
Parser.parse_constant(nil,nil).should == [nil,nil]
|
123
|
+
Parser.parse_constant("",nil).should == [nil,nil]
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should find the constant" do
|
127
|
+
Parser.parse_constant("= blah blah more blah ","=").should == ["=","blah blah more blah"]
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should find the constants with multiple characters" do
|
131
|
+
Parser.parse_constant("hey blah blah more blah ","hey").should == ["hey","blah blah more blah"]
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should return nil if not found" do
|
135
|
+
Parser.parse_constant("blah blah more blah ","=").should == [nil,"blah blah more blah"]
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should be case insensitive" do
|
139
|
+
Parser.parse_constant(" blah stuff on more blah stuff ","blah").should == ["blah","stuff on more blah stuff"]
|
140
|
+
Parser.parse_constant(" BLAH stuff on more blah stuff ","blah").should == ["BLAH","stuff on more blah stuff"]
|
141
|
+
Parser.parse_constant(" blah stuff on more blah stuff ","BLAH").should == ["blah","stuff on more blah stuff"]
|
142
|
+
end
|
149
143
|
|
150
|
-
|
144
|
+
it "should only find the first instance" do
|
145
|
+
Parser.parse_constant("one == two","==").should == [nil,"one == two"]
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
151
149
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
150
|
+
describe "#parse_word" do
|
151
|
+
|
152
|
+
it "should handle nil" do
|
153
|
+
@parser.parse_word(nil,nil).should == [nil,nil]
|
154
|
+
@parser.parse_word("",nil).should == [nil,nil]
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should look for global tokens" do
|
158
158
|
parser = Parser.new(:tokenize => "xx")
|
159
159
|
parser.parse_word("blah xx",:end).should == ["blah","xx"]
|
160
160
|
parser.parse_word("blah xx stop","stop").should == ["blah","xx stop"]
|
@@ -259,6 +259,29 @@ module Appstats
|
|
259
259
|
|
260
260
|
end
|
261
261
|
|
262
|
+
describe "#alpha?" do
|
263
|
+
|
264
|
+
it "should be false for nil" do
|
265
|
+
Parser.alpha?(nil).should == false
|
266
|
+
end
|
267
|
+
|
268
|
+
it "should be false for empty string" do
|
269
|
+
Parser.alpha?('').should == false
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should be false for non alpha string" do
|
273
|
+
Parser.alpha?('1abc').should == false
|
274
|
+
Parser.alpha?('abc2').should == false
|
275
|
+
Parser.alpha?('abc2def').should == false
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should be true for alpha string" do
|
279
|
+
Parser.alpha?('a').should == true
|
280
|
+
Parser.alpha?('abc').should == true
|
281
|
+
end
|
282
|
+
|
283
|
+
end
|
284
|
+
|
262
285
|
describe "#parse" do
|
263
286
|
|
264
287
|
|
@@ -339,6 +362,12 @@ module Appstats
|
|
339
362
|
parser.raw_results.should == [ "(", { :one => "blaa"}, "aa", "a1", { :two => "bla1"}, ")" ]
|
340
363
|
end
|
341
364
|
|
365
|
+
it "should handle alpha constants as requiring spaces" do
|
366
|
+
parser = Appstats::Parser.new(:rules => ":one group :two")
|
367
|
+
parser.parse("group_by group aha")
|
368
|
+
parser.raw_results.should == [ { :one => "group_by"}, "group", { :two => "aha"} ]
|
369
|
+
end
|
370
|
+
|
342
371
|
|
343
372
|
describe "real examples" do
|
344
373
|
|
@@ -367,6 +396,13 @@ module Appstats
|
|
367
396
|
parser.parse("# buyer-address-lookup last month").should == true
|
368
397
|
parser.raw_results.should == [{:operation=>"#"}, {:action=>"buyer-address-lookup"}, {:host=>nil}, {:contexts=>nil}, {:date=>"last month"}]
|
369
398
|
end
|
399
|
+
|
400
|
+
it "should handle group_by" do
|
401
|
+
parser = Appstats::Parser.new(:rules => ":operation :action :date on :host where :contexts group by :group_by")
|
402
|
+
parser.parse("# appstats_queries where action = abc AND contexts = 'def' || group_by like 'hik'").should == true
|
403
|
+
parser.results.should == {:operation => "#", :action => "appstats_queries", :date => nil, :host => nil, :group_by => nil, :contexts => "action = abc AND contexts = 'def' || group_by like 'hik'" }
|
404
|
+
end
|
405
|
+
|
370
406
|
|
371
407
|
end
|
372
408
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appstats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 79
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 20
|
9
|
+
- 0
|
10
|
+
version: 0.20.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrew Forward
|
@@ -181,10 +181,13 @@ files:
|
|
181
181
|
- db/migrations/20110311214833_add_appstats_results_db_connection.rb
|
182
182
|
- db/migrations/20110318203339_add_appstats_results_latest_flag.rb
|
183
183
|
- db/migrations/20110321154125_add_appstats_results_query_duration_in_seconds.rb
|
184
|
+
- db/migrations/20110330171745_create_appstats_action_contexts.rb
|
184
185
|
- db/schema.rb
|
185
186
|
- lib/appstats.rb
|
186
187
|
- lib/appstats/action.rb
|
188
|
+
- lib/appstats/action_context_key.rb
|
187
189
|
- lib/appstats/acts_as_appstatsable.rb
|
190
|
+
- lib/appstats/appstats_query.rb
|
188
191
|
- lib/appstats/ci.rake
|
189
192
|
- lib/appstats/code_injections.rb
|
190
193
|
- lib/appstats/context.rb
|
@@ -227,8 +230,10 @@ files:
|
|
227
230
|
- script/console
|
228
231
|
- script/destroy
|
229
232
|
- script/generate
|
233
|
+
- spec/action_context_key_spec.rb
|
230
234
|
- spec/action_spec.rb
|
231
235
|
- spec/acts_as_appstatsble_spec.rb
|
236
|
+
- spec/appstats_query_spec.rb
|
232
237
|
- spec/appstats_spec.rb
|
233
238
|
- spec/context_key_spec.rb
|
234
239
|
- spec/context_spec.rb
|
@@ -282,8 +287,10 @@ signing_key:
|
|
282
287
|
specification_version: 3
|
283
288
|
summary: Provide usage statistics about how your application is being used
|
284
289
|
test_files:
|
290
|
+
- spec/action_context_key_spec.rb
|
285
291
|
- spec/action_spec.rb
|
286
292
|
- spec/acts_as_appstatsble_spec.rb
|
293
|
+
- spec/appstats_query_spec.rb
|
287
294
|
- spec/appstats_spec.rb
|
288
295
|
- spec/context_key_spec.rb
|
289
296
|
- spec/context_spec.rb
|