hotdog 0.1.18 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -27,7 +27,7 @@ module Hotdog
27
27
  raise(NotImplementedError)
28
28
  end
29
29
 
30
- def execute(query, *args)
30
+ def execute(query, args=[])
31
31
  update_db
32
32
  q = query.strip
33
33
  if 0 < args.length
@@ -67,73 +67,94 @@ module Hotdog
67
67
  s.index('*') or s.index('?') or s.index('[') or s.index(']')
68
68
  end
69
69
 
70
- def host?(host_id)
71
- host_id = execute("SELECT id FROM hosts WHERE name = %s LIMIT 1", s)
72
- not host_id.nil?
73
- end
74
-
75
- def get_hosts(hosts, tags=nil)
70
+ def get_hosts(host_ids, tags=nil)
76
71
  tags ||= @options[:tags]
77
72
  update_db
78
- if 0 < tags.length
79
- result = hosts.map { |host_id|
80
- tags.map { |tag|
81
- tag_name, tag_value = tag.split(":", 2)
82
- case tag_name
83
- when "host"
84
- select_name_from_hosts_by_id(@db, host_id)
85
- else
86
- if glob?(tag_name)
87
- select_tag_values_from_hosts_tags_by_host_id_and_tag_name_glob(@db, host_id, tag_name)
88
- else
89
- select_tag_values_from_hosts_tags_by_host_id_and_tag_name(@db, host_id, tag_name)
90
- end
91
- end
92
- }
93
- }
94
- fields = tags
73
+ if host_ids.empty?
74
+ [[], []]
95
75
  else
96
- if @options[:listing]
97
- # TODO: should respect `:primary_tag`
98
- fields = []
99
- hosts = execute("SELECT id, name FROM hosts WHERE id IN (%s)" % hosts.map { "?" }.join(", "), hosts)
100
- result = hosts.map { |host_id, host_name|
101
- tag_names = select_tag_names_from_hosts_tags_by_host_id(@db, host_id)
102
- tag_names.each do |tag_name|
103
- fields << tag_name unless fields.index(tag_name)
104
- end
105
- [host_name] + fields.map { |tag_name|
106
- if glob?(tag_name)
107
- select_tag_values_from_hosts_tags_by_host_id_and_tag_name_glob(@db, host_id, tag_name)
76
+ if 0 < tags.length
77
+ fields = tags.map { |tag|
78
+ tag_name, tag_value = split_tag(tag)
79
+ tag_name
80
+ }
81
+ fields_without_host = fields.reject { |tag_name| tag_name == "host" }
82
+ if fields == fields_without_host
83
+ host_names = {}
84
+ else
85
+ host_names = Hash[execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }]
86
+ end
87
+ q1 = []
88
+ q1 << "SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags"
89
+ q1 << "INNER JOIN hosts ON hosts_tags.host_id = hosts.id"
90
+ q1 << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
91
+ q1 << "WHERE hosts_tags.host_id = ? AND tags.name IN (%s)"
92
+ q1 << "GROUP BY tags.name;"
93
+ result = host_ids.map { |host_id|
94
+ tag_values = Hash[execute(q1.join(" ") % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }]
95
+ fields.map { |tag_name|
96
+ if tag_name == "host"
97
+ host_names.fetch(host_id, "")
108
98
  else
109
- select_tag_values_from_hosts_tags_by_host_id_and_tag_name(@db, host_id, tag_name)
99
+ tag_values.fetch(tag_name, "")
110
100
  end
111
101
  }
112
102
  }
113
- fields = ["host"] + fields
103
+ [result, fields]
114
104
  else
115
- if @options[:primary_tag]
116
- fields = [@options[:primary_tag]]
117
- tag_name, tag_value = @options[:primary_tag].split(":", 2)
118
- case tag_name
119
- when "host"
120
- result = execute("SELECT name FROM hosts WHERE id IN (%s)" % hosts.map { "?" }.join(", "), hosts)
105
+ if @options[:listing]
106
+ q1 = []
107
+ q1 << "SELECT DISTINCT tags.name FROM hosts_tags"
108
+ q1 << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
109
+ q1 << "WHERE hosts_tags.host_id IN (%s);"
110
+ if @options[:primary_tag]
111
+ fields = [
112
+ @options[:primary_tag],
113
+ "host",
114
+ ] + execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.first }.reject { |tag_name|
115
+ tag_name == @options[:primary_tag]
116
+ }
121
117
  else
122
- result = hosts.map { |host_id|
123
- if glob?(tag_name)
124
- [select_tag_values_from_hosts_tags_by_host_id_and_tag_name_glob(@db, host_id, tag_name)]
118
+ fields = [
119
+ "host",
120
+ ] + execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.first }
121
+ end
122
+ host_names = Hash[execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }]
123
+ q2 = []
124
+ q2 << "SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags"
125
+ q2 << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
126
+ q2 << "WHERE hosts_tags.host_id = ? AND tags.name IN (%s)"
127
+ q2 << "GROUP BY tags.name;"
128
+ fields_without_host = fields.reject { |tag_name| tag_name == "host" }
129
+ result = host_ids.map { |host_id|
130
+ tag_values = Hash[execute(q2.join(" ") % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }]
131
+ fields.map { |tag_name|
132
+ if tag_name == "host"
133
+ host_names.fetch(host_id, "")
125
134
  else
126
- [select_tag_values_from_hosts_tags_by_host_id_and_tag_name(@db, host_id, tag_name)]
135
+ tag_values.fetch(tag_name, "")
127
136
  end
128
137
  }
129
- end
138
+ }
139
+ [result, fields]
130
140
  else
131
- fields = ["host"]
132
- result = execute("SELECT name FROM hosts WHERE id IN (%s)" % hosts.map { "?" }.join(", "), hosts)
141
+ if @options[:primary_tag]
142
+ fields = [@options[:primary_tag]]
143
+ q1 = []
144
+ q1 << "SELECT tags.value FROM hosts_tags"
145
+ q1 << "INNER JOIN hosts ON hosts_tags.host_id = hosts.id"
146
+ q1 << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
147
+ q1 << "WHERE hosts_tags.host_id IN (%s) AND tags.name = ?;"
148
+ result = execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids + [@options[:primary_tag]]).map { |row| row.to_a }
149
+ [result, fields]
150
+ else
151
+ fields = ["host"]
152
+ result = execute("SELECT name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
153
+ [result, fields]
154
+ end
133
155
  end
134
156
  end
135
157
  end
136
- [result, fields]
137
158
  end
138
159
 
139
160
  def close_db(db, options={})
@@ -172,44 +193,26 @@ module Hotdog
172
193
  create_table_hosts_tags(memory_db)
173
194
  create_index_hosts_tags(memory_db)
174
195
 
175
- code, all_tags = @dog.all_tags()
176
- logger.debug("dog.all_tags() #==> [%s, ...]" % [code.inspect])
177
- if code.to_i / 100 != 2
178
- raise("dog.all_tags() returns [%s, ...]" % [code.inspect])
179
- end
196
+ all_tags = get_all_tags()
180
197
 
181
- code, all_downtimes = @dog.get_all_downtimes()
182
- logger.debug("dog.get_all_downtimes() #==> [%s, ...]" % [code.inspect])
183
- if code.to_i / 100 != 2
184
- raise("dog.get_all_downtimes() returns [%s, ...]" % [code.inspect])
198
+ known_tags = all_tags.keys.map { |tag| split_tag(tag) }.uniq
199
+ unless known_tags.empty?
200
+ prepare(memory_db, "INSERT OR IGNORE INTO tags (name, value) VALUES %s" % known_tags.map { "(?, ?)" }.join(", ")).execute(known_tags)
185
201
  end
186
202
 
187
- now = Time.new.to_i
188
- downs = all_downtimes.select { |downtime|
189
- # active downtimes
190
- downtime["active"] and ( downtime["start"].nil? or downtime["start"] < now ) and ( downtime["end"].nil? or now <= downtime["end"] )
191
- }.map { |downtime|
192
- # find host scopes
193
- downtime["scope"].select { |scope| scope.start_with?("host:") }.map { |scope| scope.sub(/\Ahost:/, "") }
194
- }.reduce(:+)
195
- downs ||= []
196
-
197
- # for case-insensitive match of hostname
198
- downs = downs.map { |down| down.downcase }
199
-
200
- if not downs.empty?
201
- logger.info("ignore host(s) with scheduled downtimes: #{downs.inspect}")
203
+ known_hosts = all_tags.values.reduce(:+).uniq
204
+ unless known_hosts.empty?
205
+ prepare(memory_db, "INSERT OR IGNORE INTO hosts (name) VALUES %s" % known_hosts.map { "(?)" }.join(", ")).execute(known_hosts)
202
206
  end
203
207
 
204
- all_tags["tags"].each do |tag, hosts|
205
- tag_name, tag_value = tag.split(":", 2)
206
- tag_value ||= ""
207
- insert_or_ignore_into_tags(memory_db, tag_name, tag_value)
208
- hosts.each do |host_name|
209
- if not downs.include?(host_name.downcase)
210
- insert_or_ignore_into_hosts(memory_db, host_name)
211
- insert_or_replace_into_hosts_tags(memory_db, host_name, tag_name, tag_value)
212
- end
208
+ all_tags.each do |tag, hosts|
209
+ q = []
210
+ q << "INSERT OR REPLACE INTO hosts_tags (host_id, tag_id)"
211
+ q << "SELECT host.id, tag.id FROM"
212
+ q << "( SELECT id FROM hosts WHERE name IN (%s) ) AS host,"
213
+ q << "( SELECT id FROM tags WHERE name = ? AND value = ? LIMIT 1 ) AS tag;"
214
+ unless hosts.empty?
215
+ prepare(memory_db, q.join(" ") % hosts.map { "?" }.join(", ")).execute(hosts + split_tag(tag))
213
216
  end
214
217
  end
215
218
 
@@ -224,6 +227,36 @@ module Hotdog
224
227
  end
225
228
  end
226
229
 
230
+ def get_all_tags() #==> Hash<Tag,Array<Host>>
231
+ code, all_tags = @dog.all_tags()
232
+ logger.debug("dog.all_tags() #==> [%s, ...]" % [code.inspect])
233
+ if code.to_i / 100 != 2
234
+ raise("dog.all_tags() returns [%s, ...]" % [code.inspect])
235
+ end
236
+ code, all_downtimes = @dog.get_all_downtimes()
237
+ logger.debug("dog.get_all_downtimes() #==> [%s, ...]" % [code.inspect])
238
+ if code.to_i / 100 != 2
239
+ raise("dog.get_all_downtimes() returns [%s, ...]" % [code.inspect])
240
+ end
241
+ now = Time.new.to_i
242
+ downtimes = all_downtimes.select { |downtime|
243
+ # active downtimes
244
+ downtime["active"] and ( downtime["start"].nil? or downtime["start"] < now ) and ( downtime["end"].nil? or now <= downtime["end"] )
245
+ }.map { |downtime|
246
+ # find host scopes
247
+ downtime["scope"].select { |scope| scope.start_with?("host:") }.map { |scope| scope.sub(/\Ahost:/, "") }
248
+ }.reduce(:+) || []
249
+ if not downtimes.empty?
250
+ logger.info("ignore host(s) with scheduled downtimes: #{downtimes.inspect}")
251
+ end
252
+ Hash[all_tags["tags"].map { |tag, hosts| [tag, hosts.reject { |host| downtimes.include?(host) }] }]
253
+ end
254
+
255
+ def split_tag(tag)
256
+ tag_name, tag_value = tag.split(":", 2)
257
+ [tag_name, tag_value || ""]
258
+ end
259
+
227
260
  def copy_db(src, dst)
228
261
  # create index later for better insert performance
229
262
  dst.transaction do
@@ -231,15 +264,14 @@ module Hotdog
231
264
  create_table_tags(dst)
232
265
  create_table_hosts_tags(dst)
233
266
 
234
- select_from_hosts(src).each do |host_id, host_name|
235
- insert_into_hosts(dst, host_id, host_name)
236
- end
237
- select_from_tags(src).each do |tag_id, tag_name, tag_value|
238
- insert_into_tags(dst, tag_id, tag_name, tag_value)
239
- end
240
- select_from_hosts_tags(src).each do |host_id, tag_id|
241
- insert_into_hosts_tags(dst, host_id, tag_id)
242
- end
267
+ hosts = prepare(src, "SELECT id, name FROM hosts").execute().to_a
268
+ prepare(dst, "INSERT INTO hosts (id, name) VALUES %s" % hosts.map { "(?, ?)" }.join(", ")).execute(hosts) unless hosts.empty?
269
+
270
+ tags = prepare(src, "SELECT id, name, value FROM tags").execute().to_a
271
+ prepare(dst, "INSERT INTO tags (id, name, value) VALUES %s" % tags.map { "(?, ?, ?)" }.join(", ")).execute(tags) unless tags.empty?
272
+
273
+ hosts_tags = prepare(src, "SELECT host_id, tag_id FROM hosts_tags").to_a
274
+ prepare(dst, "INSERT INTO hosts_tags (host_id, tag_id) VALUES %s" % hosts_tags.map { "(?, ?)" }.join(", ")).execute(hosts_tags) unless hosts_tags.empty?
243
275
 
244
276
  create_index_hosts(dst)
245
277
  create_index_tags(dst)
@@ -247,29 +279,14 @@ module Hotdog
247
279
  end
248
280
  end
249
281
 
250
- def select_from_hosts(db)
251
- logger.debug("select_from_hosts()")
252
- prepare(db, "SELECT id, name FROM hosts").execute()
253
- end
254
-
255
- def select_from_tags(db)
256
- logger.debug("select_from_tags()")
257
- prepare(db, "SELECT id, name, value FROM tags").execute()
258
- end
259
-
260
- def select_from_hosts_tags(db)
261
- logger.debug("select_from_hosts_tags()")
262
- prepare(db, "SELECT host_id, tag_id FROM hosts_tags").execute()
263
- end
264
-
265
282
  def create_table_hosts(db)
266
283
  logger.debug("create_table_hosts()")
267
- db.execute(<<-EOS)
268
- CREATE TABLE IF NOT EXISTS hosts (
269
- id INTEGER PRIMARY KEY AUTOINCREMENT,
270
- name VARCHAR(255) NOT NULL
271
- );
272
- EOS
284
+ q = []
285
+ q << "CREATE TABLE IF NOT EXISTS hosts ("
286
+ q << "id INTEGER PRIMARY KEY AUTOINCREMENT,"
287
+ q << "name VARCHAR(255) NOT NULL COLLATE NOCASE"
288
+ q << ");"
289
+ db.execute(q.join(" "))
273
290
  end
274
291
 
275
292
  def create_index_hosts(db)
@@ -279,13 +296,13 @@ module Hotdog
279
296
 
280
297
  def create_table_tags(db)
281
298
  logger.debug("create_table_tags()")
282
- db.execute(<<-EOS)
283
- CREATE TABLE IF NOT EXISTS tags (
284
- id INTEGER PRIMARY KEY AUTOINCREMENT,
285
- name VARCHAR(200) NOT NULL,
286
- value VARCHAR(200) NOT NULL DEFAULT ""
287
- );
288
- EOS
299
+ q = []
300
+ q << "CREATE TABLE IF NOT EXISTS tags ("
301
+ q << "id INTEGER PRIMARY KEY AUTOINCREMENT,"
302
+ q << "name VARCHAR(200) NOT NULL COLLATE NOCASE,"
303
+ q << "value VARCHAR(200) NOT NULL COLLATE NOCASE"
304
+ q << ");"
305
+ db.execute(q.join(" "))
289
306
  end
290
307
 
291
308
  def create_index_tags(db)
@@ -295,85 +312,18 @@ module Hotdog
295
312
 
296
313
  def create_table_hosts_tags(db)
297
314
  logger.debug("create_table_hosts_tags()")
298
- db.execute(<<-EOS)
299
- CREATE TABLE IF NOT EXISTS hosts_tags (
300
- host_id INTEGER NOT NULL,
301
- tag_id INTEGER NOT NULL
302
- );
303
- EOS
315
+ q = []
316
+ q << "CREATE TABLE IF NOT EXISTS hosts_tags ("
317
+ q << "host_id INTEGER NOT NULL,"
318
+ q << "tag_id INTEGER NOT NULL"
319
+ q << ");"
320
+ db.execute(q.join(" "))
304
321
  end
305
322
 
306
323
  def create_index_hosts_tags(db)
307
324
  logger.debug("create_index_hosts_tags()")
308
325
  db.execute("CREATE UNIQUE INDEX IF NOT EXISTS hosts_tags_host_id_tag_id ON hosts_tags ( host_id, tag_id )")
309
326
  end
310
-
311
- def insert_into_tags(db, tag_id, tag_name, tag_value)
312
- logger.debug("insert_into_tags(%s, %s, %s)" % [tag_id.inspect, tag_name.inspect, tag_value.inspect])
313
- prepare(db, "INSERT INTO tags (id, name, value) VALUES (?, ?, ?)").execute(tag_id, tag_name, tag_value)
314
- end
315
-
316
- def insert_or_ignore_into_tags(db, tag_name, tag_value)
317
- logger.debug("insert_or_ignore_into_tags(%s, %s)" % [tag_name.inspect, tag_value.inspect])
318
- prepare(db, "INSERT OR IGNORE INTO tags (name, value) VALUES (?, ?)").execute(tag_name, tag_value)
319
- end
320
-
321
- def insert_into_hosts(db, host_id, host_name)
322
- logger.debug("insert_into_hosts(%s, %s)" % [host_id.inspect, host_name.inspect])
323
- prepare(db, "INSERT INTO hosts (id, name) VALUES (?, ?)").execute(host_id, host_name)
324
- end
325
-
326
- def insert_or_ignore_into_hosts(db, host_name)
327
- logger.debug("insert_or_ignore_into_hosts(%s)" % [host_name.inspect])
328
- prepare(db, "INSERT OR IGNORE INTO hosts (name) VALUES (?)").execute(host_name)
329
- end
330
-
331
- def insert_into_hosts_tags(db, host_id, tag_id)
332
- logger.debug("insert_into_hosts_tags(%s, %s)" % [host_id.inspect, tag_id.inspect])
333
- prepare(db, "INSERT INTO hosts_tags (host_id, tag_id) VALUES (?, ?)").execute(host_id, tag_id)
334
- end
335
-
336
- def insert_or_replace_into_hosts_tags(db, host_name, tag_name, tag_value)
337
- logger.debug("insert_or_replace_into_hosts_tags(%s, %s, %s)" % [host_name.inspect, tag_name.inspect, tag_value.inspect])
338
- prepare(db, <<-EOS).execute(host_name, tag_name, tag_value)
339
- INSERT OR REPLACE INTO hosts_tags (host_id, tag_id)
340
- SELECT host.id, tag.id FROM
341
- ( SELECT id FROM hosts WHERE LOWER(name) = LOWER(?) ) AS host,
342
- ( SELECT id FROM tags WHERE LOWER(name) = LOWER(?) AND LOWER(value) = LOWER(?) ) AS tag;
343
- EOS
344
- end
345
-
346
- def select_name_from_hosts_by_id(db, host_id)
347
- logger.debug("select_name_from_hosts_by_id(%s)" % [host_id.inspect])
348
- prepare(db, "SELECT name FROM hosts WHERE id = ? LIMIT 1").execute(host_id).map { |row| row.first }.first
349
- end
350
-
351
- def select_tag_values_from_hosts_tags_by_host_id_and_tag_name_glob(db, host_id, tag_name)
352
- logger.debug("select_tag_values_from_hosts_tags_by_host_id_and_tag_name_glob(%s, %s)" % [host_id.inspect, tag_name.inspect])
353
- prepare(db, <<-EOS).execute(host_id, tag_name).map { |row| row.first }.join(",")
354
- SELECT tags.value FROM hosts_tags
355
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
356
- WHERE hosts_tags.host_id = ? AND LOWER(tags.name) GLOB LOWER(?);
357
- EOS
358
- end
359
-
360
- def select_tag_values_from_hosts_tags_by_host_id_and_tag_name(db, host_id, tag_name)
361
- logger.debug("select_tag_values_from_hosts_tags_by_host_id_and_tag_name(%s, %s)" % [host_id.inspect, tag_name.inspect])
362
- prepare(db, <<-EOS).execute(host_id, tag_name).map { |row| row.first }.join(",")
363
- SELECT tags.value FROM hosts_tags
364
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
365
- WHERE hosts_tags.host_id = ? AND LOWER(tags.name) = LOWER(?);
366
- EOS
367
- end
368
-
369
- def select_tag_names_from_hosts_tags_by_host_id(db, host_id)
370
- logger.debug("select_tag_names_from_hosts_tags_by_host_id(%s)" % [host_id.inspect])
371
- prepare(db, <<-EOS).execute(host_id).map { |row| row.first }
372
- SELECT DISTINCT tags.name FROM hosts_tags
373
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
374
- WHERE hosts_tags.host_id = ?;
375
- EOS
376
- end
377
327
  end
378
328
  end
379
329
  end
@@ -4,10 +4,15 @@ module Hotdog
4
4
  module Formatters
5
5
  class Ltsv < BaseFormatter
6
6
  def format(result, options={})
7
- fields = options.fetch(:fields, [])
8
- result.map { |row|
9
- fields.zip(row).map { |column| column.join(":") }.join("\t")
10
- }.join("\n") + "\n"
7
+ if options[:fields]
8
+ result.map { |row|
9
+ options[:fields].zip(row).map { |column| column.join(":") }.join("\t")
10
+ }.join("\n") + "\n"
11
+ else
12
+ result.map { |row|
13
+ row.join("\t")
14
+ }.join("\n") + "\n"
15
+ end
11
16
  end
12
17
  end
13
18
  end
@@ -27,7 +27,7 @@ module Hotdog
27
27
  },
28
28
  ] + result.map { |row|
29
29
  row.zip(field_length).map { |field, length|
30
- padding = length - ((field.nil?) ? 0 : field.length)
30
+ padding = length - ((field.nil?) ? 0 : field.to_s.length)
31
31
  field.to_s + (" " * padding)
32
32
  }
33
33
  }
@@ -1,3 +1,3 @@
1
1
  module Hotdog
2
- VERSION = "0.1.18"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+ require "hotdog/application"
3
+ require "hotdog/commands"
4
+ require "hotdog/commands/hosts"
5
+ require "hotdog/commands/search"
6
+ require "hotdog/commands/tags"
7
+
8
+ describe "application" do
9
+ let(:app) {
10
+ Hotdog::Application.new
11
+ }
12
+
13
+ before(:each) do
14
+ ENV["DATADOG_API_KEY"] = "DATADOG_API_KEY"
15
+ ENV["DATADOG_APPLICATION_KEY"] = "DATADOG_APPLICATION_KEY"
16
+ end
17
+
18
+ it "generates proper class name from file name" do
19
+ expect(app.__send__(:const_name, "csv")).to eq("Csv")
20
+ expect(app.__send__(:const_name, "json")).to eq("Json")
21
+ expect(app.__send__(:const_name, "pssh")).to eq("Pssh")
22
+ expect(app.__send__(:const_name, "parallel-ssh")).to eq("ParallelSsh")
23
+ end
24
+
25
+ it "returns proper class by name" do
26
+ expect(app.__send__(:get_command, "hosts")).to be(Hotdog::Commands::Hosts)
27
+ expect(app.__send__(:get_command, "search")).to be(Hotdog::Commands::Search)
28
+ expect(app.__send__(:get_command, "tags")).to be(Hotdog::Commands::Tags)
29
+ end
30
+
31
+ it "raises error if the action is base-command" do
32
+ expect {
33
+ app.main(["base-command"])
34
+ }.to raise_error(NotImplementedError)
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+ require "hotdog/formatters"
3
+ require "hotdog/formatters/csv"
4
+
5
+ describe "csv" do
6
+ let(:fmt) {
7
+ Hotdog::Formatters::Csv.new
8
+ }
9
+
10
+ it "generates csv without headers" do
11
+ options = {
12
+ headers: false,
13
+ }
14
+ expect(fmt.format([["foo", "aaa", 1], ["bar", "bbb", 2], ["baz", "ccc", 3]], options)).to eq(<<-EOS)
15
+ foo,aaa,1
16
+ bar,bbb,2
17
+ baz,ccc,3
18
+ EOS
19
+ end
20
+
21
+ it "generates csv with headers" do
22
+ options = {
23
+ headers: true,
24
+ fields: ["key1", "key2", "val1"],
25
+ }
26
+ expect(fmt.format([["foo", "aaa", 1], ["bar", "bbb", 2], ["baz", "ccc", 3]], options)).to eq(<<-EOS)
27
+ key1,key2,val1
28
+ foo,aaa,1
29
+ bar,bbb,2
30
+ baz,ccc,3
31
+ EOS
32
+ end
33
+ end
@@ -0,0 +1,66 @@
1
+ require "spec_helper"
2
+ require "hotdog/formatters"
3
+ require "hotdog/formatters/json"
4
+
5
+ describe "json" do
6
+ let(:fmt) {
7
+ Hotdog::Formatters::Json.new
8
+ }
9
+
10
+ it "generates json without headers" do
11
+ options = {
12
+ headers: false,
13
+ }
14
+ expect(fmt.format([["foo", "aaa", 1], ["bar", "bbb", 2], ["baz", "ccc", 3]], options)).to eq(<<-EOS)
15
+ [
16
+ [
17
+ "foo",
18
+ "aaa",
19
+ 1
20
+ ],
21
+ [
22
+ "bar",
23
+ "bbb",
24
+ 2
25
+ ],
26
+ [
27
+ "baz",
28
+ "ccc",
29
+ 3
30
+ ]
31
+ ]
32
+ EOS
33
+ end
34
+
35
+ it "generates json with headers" do
36
+ options = {
37
+ headers: true,
38
+ fields: ["key1", "key2", "val1"],
39
+ prettyprint: false,
40
+ }
41
+ expect(fmt.format([["foo", "aaa", 1], ["bar", "bbb", 2], ["baz", "ccc", 3]], options)).to eq(<<-EOS)
42
+ [
43
+ [
44
+ "key1",
45
+ "key2",
46
+ "val1"
47
+ ],
48
+ [
49
+ "foo",
50
+ "aaa",
51
+ 1
52
+ ],
53
+ [
54
+ "bar",
55
+ "bbb",
56
+ 2
57
+ ],
58
+ [
59
+ "baz",
60
+ "ccc",
61
+ 3
62
+ ]
63
+ ]
64
+ EOS
65
+ end
66
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+ require "hotdog/formatters"
3
+ require "hotdog/formatters/ltsv"
4
+
5
+ describe "ltsv" do
6
+ let(:fmt) {
7
+ Hotdog::Formatters::Ltsv.new
8
+ }
9
+
10
+ it "generates ltsv without headers" do
11
+ options = {
12
+ headers: false,
13
+ }
14
+ expect(fmt.format([["foo", "aaa", 1], ["bar", "bbb", 2], ["baz", "ccc", 3]], options)).to eq(<<-EOS)
15
+ foo\taaa\t1
16
+ bar\tbbb\t2
17
+ baz\tccc\t3
18
+ EOS
19
+ end
20
+
21
+ it "generates ltsv with headers" do
22
+ options = {
23
+ headers: true,
24
+ fields: ["key1", "key2", "val1"],
25
+ }
26
+ expect(fmt.format([["foo", "aaa", 1], ["bar", "bbb", 2], ["baz", "ccc", 3]], options)).to eq(<<-EOS)
27
+ key1:foo\tkey2:aaa\tval1:1
28
+ key1:bar\tkey2:bbb\tval1:2
29
+ key1:baz\tkey2:ccc\tval1:3
30
+ EOS
31
+ end
32
+ end