keen-cli 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +77 -49
- data/keen-cli.gemspec +1 -1
- data/lib/keen-cli/batch_processor.rb +104 -0
- data/lib/keen-cli/cli.rb +9 -234
- data/lib/keen-cli/events.rb +70 -0
- data/lib/keen-cli/projects.rb +51 -0
- data/lib/keen-cli/queries.rb +138 -0
- data/lib/keen-cli/shared.rb +28 -0
- data/lib/keen-cli/utils.rb +18 -0
- data/lib/keen-cli/version.rb +1 -1
- data/lib/keen-cli.rb +16 -0
- data/spec/keen-cli/batch_processor_spec.rb +134 -0
- data/spec/keen-cli/cli_spec.rb +4 -161
- data/spec/keen-cli/events_spec.rb +41 -0
- data/spec/keen-cli/projects_spec.rb +42 -0
- data/spec/keen-cli/queries_spec.rb +106 -0
- data/spec/spec_helper.rb +13 -0
- metadata +17 -4
@@ -0,0 +1,51 @@
|
|
1
|
+
module KeenCli
|
2
|
+
|
3
|
+
class CLI < Thor
|
4
|
+
|
5
|
+
desc 'projects:describe', 'Print information about a project'
|
6
|
+
map 'projects:describe' => :projects_describe
|
7
|
+
shared_options
|
8
|
+
|
9
|
+
def projects_describe
|
10
|
+
Utils.process_options!(options)
|
11
|
+
Keen.project_info.tap do |info|
|
12
|
+
Utils.out_json(info, options)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'projects:collections', 'Print information about a project\'s collections'
|
17
|
+
map 'projects:collections' => :projects_collections
|
18
|
+
shared_options
|
19
|
+
|
20
|
+
def projects_collections
|
21
|
+
Utils.process_options!(options)
|
22
|
+
Keen.event_collections.tap do |collections|
|
23
|
+
Utils.out_json(collections, options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'projects:open', 'Open a project\'s overview page in a browser'
|
28
|
+
map 'projects:open' => :projects_open
|
29
|
+
shared_options
|
30
|
+
|
31
|
+
def projects_open
|
32
|
+
Utils.process_options!(options)
|
33
|
+
"https://keen.io/project/#{Keen.project_id}".tap do |projects_url|
|
34
|
+
`open #{projects_url}`
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'projects:workbench', 'Open a project\'s workbench page in a browser'
|
39
|
+
map 'projects:workbench' => :projects_workbench
|
40
|
+
shared_options
|
41
|
+
|
42
|
+
def projects_workbench
|
43
|
+
Utils.process_options!(options)
|
44
|
+
"https://keen.io/project/#{Keen.project_id}/workbench".tap do |project_url|
|
45
|
+
`open #{project_url}`
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module KeenCli
|
2
|
+
|
3
|
+
class CLI < Thor
|
4
|
+
|
5
|
+
def self.query_options
|
6
|
+
self.collection_options
|
7
|
+
option :"analysis-type", :aliases => ['-a']
|
8
|
+
option :"group-by", :aliases => ['-g']
|
9
|
+
option :"target-property", :aliases => ['-y']
|
10
|
+
option :interval, :aliases => ['-i']
|
11
|
+
option :timeframe, :aliases => ['-t']
|
12
|
+
option :filters, :aliases => ['-f']
|
13
|
+
option :percentile
|
14
|
+
option :"property-names"
|
15
|
+
option :latest
|
16
|
+
option :email
|
17
|
+
option :start, :aliases => ['s']
|
18
|
+
option :end, :aliases => ['e']
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'queries:run', 'Run a query and print the result'
|
22
|
+
map 'queries:run' => :queries_run
|
23
|
+
shared_options
|
24
|
+
query_options
|
25
|
+
data_options
|
26
|
+
def queries_run(analysis_type=nil)
|
27
|
+
|
28
|
+
Utils.process_options!(options)
|
29
|
+
|
30
|
+
collection = Utils.get_collection_name(options)
|
31
|
+
raise "No collection given!" unless collection
|
32
|
+
|
33
|
+
analysis_type = analysis_type || options[:"analysis-type"]
|
34
|
+
raise "No analysis type given!" unless analysis_type
|
35
|
+
|
36
|
+
query_options = to_query_options(options)
|
37
|
+
|
38
|
+
Keen.query(analysis_type, collection, query_options).tap do |result|
|
39
|
+
if result.is_a?(Hash) || result.is_a?(Array)
|
40
|
+
Utils.out_json(result, options)
|
41
|
+
else
|
42
|
+
Utils.out(result, options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'queries:url', 'Print the URL for a query'
|
48
|
+
map 'queries:url' => :queries_url
|
49
|
+
shared_options
|
50
|
+
query_options
|
51
|
+
data_options
|
52
|
+
option :'exclude-api-key'
|
53
|
+
|
54
|
+
def queries_url
|
55
|
+
|
56
|
+
Utils.process_options!(options)
|
57
|
+
|
58
|
+
collection = Utils.get_collection_name(options)
|
59
|
+
raise "No collection given!" unless collection
|
60
|
+
|
61
|
+
analysis_type = options[:"analysis-type"]
|
62
|
+
raise "No analysis type given!" unless analysis_type
|
63
|
+
|
64
|
+
query_options = to_query_options(options)
|
65
|
+
|
66
|
+
Keen.query_url(analysis_type, collection, query_options,
|
67
|
+
{ :exclude_api_key => options[:'exclude-api-key']}).tap do |url|
|
68
|
+
Utils.out(url, options)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
ANALYSIS_TYPES = %w(average count count-unique extraction median minimum maximum sum percentile select-unique)
|
73
|
+
|
74
|
+
ANALYSIS_TYPES.each do |analysis_type|
|
75
|
+
underscored_analysis_type = analysis_type.sub('-', '_')
|
76
|
+
desc analysis_type, "Alias for queries:run -a #{underscored_analysis_type}"
|
77
|
+
map analysis_type => method_name = "queries_run_#{underscored_analysis_type}"
|
78
|
+
shared_options
|
79
|
+
query_options
|
80
|
+
data_options
|
81
|
+
self.send(:define_method, method_name) { queries_run(underscored_analysis_type) }
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def to_query_options(options)
|
87
|
+
|
88
|
+
data = nil
|
89
|
+
|
90
|
+
if $stdin.tty?
|
91
|
+
data = options[:data]
|
92
|
+
else
|
93
|
+
ARGV.clear
|
94
|
+
ARGF.each_line do |line|
|
95
|
+
data += line
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# setup a holder for query options
|
100
|
+
q_options = {}
|
101
|
+
|
102
|
+
# if data is provided, parse it and merge it
|
103
|
+
unless data.nil?
|
104
|
+
data_options = JSON.parse(data)
|
105
|
+
q_options.merge!(data_options)
|
106
|
+
end
|
107
|
+
|
108
|
+
# copy query options in intelligently
|
109
|
+
q_options[:group_by] = options[:"group-by"]
|
110
|
+
q_options[:target_property] = options[:"target-property"]
|
111
|
+
q_options[:interval] = options[:interval]
|
112
|
+
q_options[:timeframe] = options[:timeframe]
|
113
|
+
q_options[:filters] = options[:filters]
|
114
|
+
q_options[:percentile] = options[:percentile]
|
115
|
+
q_options[:latest] = options[:latest]
|
116
|
+
q_options[:email] = options[:email]
|
117
|
+
|
118
|
+
if property_names = options[:"property-names"]
|
119
|
+
q_options[:property_names] = property_names.split(",")
|
120
|
+
end
|
121
|
+
|
122
|
+
if start_time = options[:start]
|
123
|
+
q_options[:timeframe] = { :start => start_time }
|
124
|
+
end
|
125
|
+
|
126
|
+
if end_time = options[:end]
|
127
|
+
q_options[:timeframe] = q_options[:timeframe] || {}
|
128
|
+
q_options[:timeframe][:end] = end_time
|
129
|
+
end
|
130
|
+
|
131
|
+
q_options.delete_if { |k, v| v.nil? }
|
132
|
+
|
133
|
+
q_options
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module KeenCli
|
2
|
+
|
3
|
+
class CLI < Thor
|
4
|
+
|
5
|
+
def self.shared_options
|
6
|
+
option :project, :aliases => ['-p']
|
7
|
+
option :"master-key", :aliases => ['-k']
|
8
|
+
option :"read-key", :aliases => ['-r']
|
9
|
+
option :"write-key", :aliases => ['-w']
|
10
|
+
option :pretty, :type => :boolean, :default => true
|
11
|
+
option :silent, :type => :boolean, :default => false
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.collection_options
|
15
|
+
option :collection, :aliases => ['-c']
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.data_options
|
19
|
+
option :data, :aliases => ['-d']
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.file_options
|
23
|
+
option :file, :aliases => ['-f']
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/keen-cli/utils.rb
CHANGED
@@ -24,6 +24,24 @@ module KeenCli
|
|
24
24
|
|
25
25
|
end
|
26
26
|
|
27
|
+
def out_json(hash, options)
|
28
|
+
if options[:silent]
|
29
|
+
# do nothing
|
30
|
+
elsif options[:pretty]
|
31
|
+
puts JSON.pretty_generate(hash)
|
32
|
+
else
|
33
|
+
puts JSON.generate(hash)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def out(str, options)
|
38
|
+
if options[:silent]
|
39
|
+
# do nothing
|
40
|
+
else
|
41
|
+
puts str
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
27
45
|
def get_collection_name(options)
|
28
46
|
options["collection"] || options["event_collection"] || ENV['KEEN_COLLECTION_NAME']
|
29
47
|
end
|
data/lib/keen-cli/version.rb
CHANGED
data/lib/keen-cli.rb
CHANGED
@@ -8,3 +8,19 @@ Dotenv.load
|
|
8
8
|
module KeenCli
|
9
9
|
|
10
10
|
end
|
11
|
+
|
12
|
+
class Hash
|
13
|
+
|
14
|
+
def deep_merge(hash)
|
15
|
+
target = dup
|
16
|
+
hash.keys.each do |key|
|
17
|
+
if hash[key].is_a? Hash and self[key].is_a? Hash
|
18
|
+
target[key] = target[key].deep_merge(hash[key])
|
19
|
+
next
|
20
|
+
end
|
21
|
+
target[key] = hash[key]
|
22
|
+
end
|
23
|
+
target
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module KeenCli
|
4
|
+
|
5
|
+
describe BatchProcessor do
|
6
|
+
|
7
|
+
let(:batch_processor) { BatchProcessor.new('signups') }
|
8
|
+
|
9
|
+
describe 'new' do
|
10
|
+
|
11
|
+
it 'defaults batch size to 1000' do
|
12
|
+
expect(batch_processor.batch_size).to eq(1000)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sets the collection' do
|
16
|
+
expect(batch_processor.collection).to eq('signups')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'sets the pretty output' do
|
20
|
+
batch_processor = BatchProcessor.new('signups', :pretty => true)
|
21
|
+
expect(batch_processor.pretty).to eq(true)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'sets the silent output' do
|
25
|
+
batch_processor = BatchProcessor.new('signups', :silent => true)
|
26
|
+
expect(batch_processor.silent).to eq(true)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets csv and merges csv options with defaults' do
|
30
|
+
csv_processor = BatchProcessor.new('signups', :csv => true, :csv_options => { :headers => ['foo'] })
|
31
|
+
expect(csv_processor.csv).to eq(true)
|
32
|
+
expect(csv_processor.csv_options).to eq(
|
33
|
+
:headers => ['foo'], :converters => :all)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'conversion' do
|
39
|
+
|
40
|
+
let(:batch_processor) { BatchProcessor.new('signups') }
|
41
|
+
|
42
|
+
it 'converts a JSON string to a hash' do
|
43
|
+
batch_processor.add('{ "apple": "sauce", "banana": "pancakes" }')
|
44
|
+
expect(batch_processor.events.first).to eq({
|
45
|
+
"apple" => "sauce",
|
46
|
+
"banana" => "pancakes"
|
47
|
+
})
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'converts a param string to a hash' do
|
51
|
+
batch_processor.params = true
|
52
|
+
batch_processor.add('apple=sauce&banana=pancakes')
|
53
|
+
expect(batch_processor.events.first).to eq({
|
54
|
+
"apple" => "sauce",
|
55
|
+
"banana" => "pancakes"
|
56
|
+
})
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'converts a csv line to a hash' do
|
60
|
+
batch_processor.csv = true
|
61
|
+
batch_processor.csv_options[:headers] = ['apple', 'banana']
|
62
|
+
batch_processor.add('sauce,pancakes')
|
63
|
+
expect(batch_processor.events.first).to eq({
|
64
|
+
"apple" => "sauce",
|
65
|
+
"banana" => "pancakes"
|
66
|
+
})
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'converts a csv line with dotted properties to nested hashes' do
|
70
|
+
batch_processor.csv = true
|
71
|
+
batch_processor.csv_options[:headers] = ['keen.timestamp', 'apple.date', 'apple.banana.cherry', 'apple.banana.walnut']
|
72
|
+
batch_processor.add('2012-08-09,pudding,smoothie,butter')
|
73
|
+
expect(batch_processor.events.first).to eq({
|
74
|
+
"apple" => {
|
75
|
+
"date" => "pudding",
|
76
|
+
"banana" => {
|
77
|
+
"cherry" => "smoothie",
|
78
|
+
"walnut" => "butter"
|
79
|
+
}
|
80
|
+
},
|
81
|
+
"keen" => {
|
82
|
+
"timestamp" => "2012-08-09"
|
83
|
+
}
|
84
|
+
})
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'add' do
|
90
|
+
|
91
|
+
let(:batch_processor) { BatchProcessor.new('signups', :silent => true) }
|
92
|
+
|
93
|
+
it 'starts empty' do
|
94
|
+
expect(batch_processor.size).to eq(0)
|
95
|
+
expect(batch_processor.events).to be_empty
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'adds events to an array up to batch size and increments count' do
|
99
|
+
batch_processor.add('{ "apple": "sauce", "banana": "pancakes" }')
|
100
|
+
expect(batch_processor.size).to eq(1)
|
101
|
+
expect(batch_processor.events.first).to eq({
|
102
|
+
"apple" => "sauce",
|
103
|
+
"banana" => "pancakes"
|
104
|
+
})
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'flushes at the batch size' do
|
108
|
+
stub_request(:post, "https://api.keen.io/3.0/projects/#{Keen.project_id}/events").
|
109
|
+
with(:body => "{\"signups\":[{\"apple\":\"sauce\",\"banana\":\"pancakes\"},{\"apple\":\"sauce\",\"banana\":\"pancakes\"}]}").
|
110
|
+
to_return(:status => 200, :body => { "signups" => [{ "created" => true }] }.to_json)
|
111
|
+
batch_processor.batch_size = 2
|
112
|
+
batch_processor.add('{ "apple": "sauce", "banana": "pancakes" }')
|
113
|
+
expect(batch_processor.size).to eq(1)
|
114
|
+
batch_processor.add('{ "apple": "sauce", "banana": "pancakes" }')
|
115
|
+
expect(batch_processor.size).to eq(0)
|
116
|
+
expect(batch_processor.events).to be_empty
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'flush' do
|
122
|
+
|
123
|
+
let(:batch_processor) { BatchProcessor.new('signups') }
|
124
|
+
|
125
|
+
it 'does not flush if there are no events' do
|
126
|
+
batch_processor.size = 0
|
127
|
+
batch_processor.flush
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
data/spec/keen-cli/cli_spec.rb
CHANGED
@@ -2,171 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe KeenCli::CLI do
|
4
4
|
|
5
|
-
let(:project_id) {
|
6
|
-
let(:master_key) {
|
7
|
-
let(:read_key) {
|
8
|
-
let(:write_key) {
|
9
|
-
|
10
|
-
def start(str=nil)
|
11
|
-
KeenCli::CLI.start(str ? str.split(" ") : [])
|
12
|
-
end
|
13
|
-
|
14
|
-
before do
|
15
|
-
Keen.project_id = project_id
|
16
|
-
Keen.read_key = read_key
|
17
|
-
Keen.write_key = write_key
|
18
|
-
Keen.master_key = master_key
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'prints help by default' do
|
22
|
-
_, options = start
|
23
|
-
expect(_).to be_empty
|
24
|
-
end
|
5
|
+
let(:project_id) { Keen.project_id }
|
6
|
+
let(:master_key) { Keen.master_key }
|
7
|
+
let(:read_key) { Keen.read_key }
|
8
|
+
let(:write_key) { Keen.write_key }
|
25
9
|
|
26
10
|
it 'prints version info if -v is used' do
|
27
11
|
_, options = start "-v"
|
28
12
|
expect(_).to match /version/
|
29
13
|
end
|
30
14
|
|
31
|
-
describe 'project:describe' do
|
32
|
-
it 'gets the project' do
|
33
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}"
|
34
|
-
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
35
|
-
_, options = start 'project:describe'
|
36
|
-
expect(_).to eq("fake" => "response")
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'uses the project id param if present' do
|
40
|
-
url = "https://api.keen.io/3.0/projects/GGGG"
|
41
|
-
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
42
|
-
_, options = start 'project:describe --project GGGG'
|
43
|
-
expect(_).to eq("fake" => "response")
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe 'project:collections' do
|
48
|
-
it 'prints the project\'s collections' do
|
49
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/events"
|
50
|
-
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
51
|
-
_, options = start 'project:collections'
|
52
|
-
expect(_).to eq("fake" => "response")
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'uses the project id param if present' do
|
56
|
-
url = "https://api.keen.io/3.0/projects/GGGG/events"
|
57
|
-
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
58
|
-
_, options = start 'project:collections --project GGGG'
|
59
|
-
expect(_).to eq("fake" => "response")
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe 'queries:run' do
|
64
|
-
it 'runs the query using certain params' do
|
65
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/count?event_collection=minecraft-deaths"
|
66
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
67
|
-
_, options = start 'queries:run --analysis-type count --collection minecraft-deaths'
|
68
|
-
expect(_).to eq(10)
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'runs the query using aliased params' do
|
72
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/count?event_collection=minecraft-deaths"
|
73
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
74
|
-
_, options = start 'queries:run -a count -c minecraft-deaths'
|
75
|
-
expect(_).to eq(10)
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'converts dashes to underscores for certain properties' do
|
79
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/count?event_collection=minecraft-deaths&group_by=foo&target_property=bar"
|
80
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
81
|
-
_, options = start 'queries:run --analysis-type count --collection minecraft-deaths --group-by foo --target-property bar'
|
82
|
-
expect(_).to eq(10)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'accepts extraction-specific properties' do
|
86
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/extraction?event_collection=minecraft-deaths&property_names=%5B%22foo%22,%22bar%22%5D&latest=1&email=bob@bob.io"
|
87
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
88
|
-
_, options = start 'queries:run --analysis-type extraction --collection minecraft-deaths --property-names foo,bar --latest 1 --email bob@bob.io'
|
89
|
-
expect(_).to eq(10)
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'converts comma-delimited property names to an array' do
|
93
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/extraction?event_collection=minecraft-deaths&property_names=%5B%22foo%22,%22bar%22%5D"
|
94
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
95
|
-
_, options = start 'queries:run --analysis-type extraction --collection minecraft-deaths --property-names foo,bar'
|
96
|
-
expect(_).to eq(10)
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
it 'uses a data option to take in query JSON' do
|
101
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/count?event_collection=minecraft-deaths"
|
102
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
103
|
-
_, options = start 'queries:run --analysis-type count --data {"event_collection":"minecraft-deaths"}'
|
104
|
-
expect(_).to eq(10)
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'converts a start parameter into an absolute timeframe' do
|
108
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/count?event_collection=minecraft-deaths&timeframe=%7B%22start%22:%222014-07-06T12:00:00Z%22%7D"
|
109
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
110
|
-
_, options = start 'queries:run --collection minecraft-deaths --analysis-type count --start 2014-07-06T12:00:00Z'
|
111
|
-
expect(_).to eq(10)
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'converts an end parameter into an absolute timeframe' do
|
115
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/count?event_collection=minecraft-deaths&timeframe=%7B%22end%22:%222014-07-06T12:00:00Z%22%7D"
|
116
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
117
|
-
_, options = start 'queries:run --collection minecraft-deaths --analysis-type count --end 2014-07-06T12:00:00Z'
|
118
|
-
expect(_).to eq(10)
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'converts start and end parameters into an absolute timeframe' do
|
122
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/count?event_collection=minecraft-deaths&timeframe=%7B%22start%22:%222014-07-06T12:00:00Z%22,%22end%22:%222014-07-08T12:00:00Z%22%7D"
|
123
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
124
|
-
_, options = start 'queries:run --collection minecraft-deaths --analysis-type count --start 2014-07-06T12:00:00Z --end 2014-07-08T12:00:00Z'
|
125
|
-
expect(_).to eq(10)
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
describe "queries:run aliases" do
|
131
|
-
KeenCli::CLI::ANALYSIS_TYPES.each do |analysis_type|
|
132
|
-
describe analysis_type do
|
133
|
-
it "aliases to queries run, passing along the #{analysis_type} analysis type" do
|
134
|
-
underscored_analysis_type = analysis_type.sub('-', '_')
|
135
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/queries/#{underscored_analysis_type}?event_collection=minecraft-deaths"
|
136
|
-
stub_request(:get, url).to_return(:body => { :result => 10 }.to_json)
|
137
|
-
_, options = start "#{analysis_type} --collection minecraft-deaths"
|
138
|
-
expect(_).to eq(10)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
describe 'events:add' do
|
145
|
-
it 'should accept JSON events from a data param' do
|
146
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/events/minecraft-deaths"
|
147
|
-
stub_request(:post, url).
|
148
|
-
with(:body => { "foo" => 1 }).
|
149
|
-
to_return(:body => { :created => true }.to_json)
|
150
|
-
_, options = start 'events:add --collection minecraft-deaths --data {"foo":1}'
|
151
|
-
expect(_).to eq("created" => true)
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'should accept JSON events from a file param' do
|
155
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/events/minecraft-deaths"
|
156
|
-
stub_request(:post, "https://api.keen.io/3.0/projects/AAAAAAA/events").
|
157
|
-
with(:body => "{\"minecraft-deaths\":[{\"foo\":1},{\"foo\":2},{\"foo\":3}]}").
|
158
|
-
to_return(:body => { :created => true }.to_json)
|
159
|
-
_, options = start "events:add --collection minecraft-deaths --file #{File.expand_path('../../fixtures/events.json', __FILE__)}"
|
160
|
-
expect(_).to eq("created" => true)
|
161
|
-
end
|
162
|
-
|
163
|
-
it 'should accept JSON events from a file param in CSV format' do
|
164
|
-
url = "https://api.keen.io/3.0/projects/#{project_id}/events/minecraft-deaths"
|
165
|
-
stub_request(:post, "https://api.keen.io/3.0/projects/AAAAAAA/events").
|
166
|
-
with(:body => "{\"minecraft-deaths\":[{\"foo\":1},{\"foo\":2},{\"foo\":3}]}").
|
167
|
-
to_return(:body => { :created => true }.to_json)
|
168
|
-
_, options = start "events:add --collection minecraft-deaths --csv --file #{File.expand_path('../../fixtures/events.csv', __FILE__)}"
|
169
|
-
expect(_).to eq("created" => true)
|
170
|
-
end
|
171
|
-
end
|
172
15
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KeenCli::CLI do
|
4
|
+
|
5
|
+
describe 'events:add' do
|
6
|
+
|
7
|
+
it 'adds a blank event' do
|
8
|
+
stub_request(:post, "https://api.keen.io/3.0/projects/#{Keen.project_id}/events").
|
9
|
+
with(:body => "{\"minecraft-deaths\":[{}]}").
|
10
|
+
to_return(:body => { :created => true }.to_json)
|
11
|
+
_, options = start 'events:add --collection minecraft-deaths'
|
12
|
+
expect(_).to eq(1)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'accepts JSON events from a data param' do
|
16
|
+
stub_request(:post, "https://api.keen.io/3.0/projects/#{Keen.project_id}/events").
|
17
|
+
with(:body => "{\"minecraft-deaths\":[{\"foo\":1}]}").
|
18
|
+
to_return(:body => { :created => true }.to_json)
|
19
|
+
_, options = start 'events:add --collection minecraft-deaths --data {"foo":1}'
|
20
|
+
expect(_).to eq(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'accepts JSON events from a file param' do
|
24
|
+
stub_request(:post, "https://api.keen.io/3.0/projects/#{Keen.project_id}/events").
|
25
|
+
with(:body => "{\"minecraft-deaths\":[{\"foo\":1},{\"foo\":2},{\"foo\":3}]}").
|
26
|
+
to_return(:body => { :created => true }.to_json)
|
27
|
+
_, options = start "events:add --collection minecraft-deaths --file #{File.expand_path('../../fixtures/events.json', __FILE__)}"
|
28
|
+
expect(_).to eq(3)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'accepts JSON events from a file param in CSV format' do
|
32
|
+
stub_request(:post, "https://api.keen.io/3.0/projects/#{Keen.project_id}/events").
|
33
|
+
with(:body => "{\"minecraft-deaths\":[{\"foo\":1},{\"foo\":2},{\"foo\":3}]}").
|
34
|
+
to_return(:body => { :created => true }.to_json)
|
35
|
+
_, options = start "events:add --collection minecraft-deaths --csv --file #{File.expand_path('../../fixtures/events.csv', __FILE__)}"
|
36
|
+
expect(_).to eq(4)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KeenCli::CLI do
|
4
|
+
|
5
|
+
let(:project_id) { Keen.project_id }
|
6
|
+
let(:master_key) { Keen.master_key }
|
7
|
+
let(:read_key) { Keen.read_key }
|
8
|
+
let(:write_key) { Keen.write_key }
|
9
|
+
|
10
|
+
describe 'projects:describe' do
|
11
|
+
it 'gets the project' do
|
12
|
+
url = "https://api.keen.io/3.0/projects/#{project_id}"
|
13
|
+
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
14
|
+
_, options = start 'projects:describe'
|
15
|
+
expect(_).to eq("fake" => "response")
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'uses the project id param if present' do
|
19
|
+
url = "https://api.keen.io/3.0/projects/GGGG"
|
20
|
+
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
21
|
+
_, options = start 'projects:describe --project GGGG'
|
22
|
+
expect(_).to eq("fake" => "response")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'projects:collections' do
|
27
|
+
it 'prints the project\'s collections' do
|
28
|
+
url = "https://api.keen.io/3.0/projects/#{project_id}/events"
|
29
|
+
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
30
|
+
_, options = start 'projects:collections'
|
31
|
+
expect(_).to eq("fake" => "response")
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'uses the project id param if present' do
|
35
|
+
url = "https://api.keen.io/3.0/projects/GGGG/events"
|
36
|
+
stub_request(:get, url).to_return(:body => { :fake => "response" }.to_json)
|
37
|
+
_, options = start 'projects:collections --project GGGG'
|
38
|
+
expect(_).to eq("fake" => "response")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|