├── .gitignore ├── .rspec ├── .travis.yml ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── bin └── influxdb-cli ├── influxdb-cli.gemspec ├── lib ├── influxdb_client.rb └── influxdb_client │ ├── client.rb │ └── version.rb └── spec ├── influxdb_client └── client_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | influxdb.log 19 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | # - 1.9.3 4 | # - 1.9.2 5 | - 2.0.0 6 | # - 2.1.0 7 | # - ruby-head 8 | - jruby-19mode 9 | # - jruby-head 10 | 11 | notifications: 12 | email: 13 | on_success: change 14 | on_failure: always 15 | 16 | script: bundle exec rspec spec 17 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Pablo Cantero 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | InfluxDB-CLI 2 | ============ 3 | 4 | Ruby CLI for InfluxDB is a simple Ruby console (empowered with [Pry](https://github.com/pry/pry)) connected to an InfluxDB server using given parameters. In order to connect to InfluxDB, it uses [influxdb-ruby](https://github.com/influxdb/influxdb-ruby), so you can access any available method from influxdb-ruby in the console through the `db` variable i.e.: `db.write_point(name, data)`, `db.query('SELECT value FROM response_times')` etc. 5 | 6 | [![Build Status](https://secure.travis-ci.org/phstc/influxdb-cli.png)](http://travis-ci.org/phstc/influxdb-cli) 7 | 8 | ### Installation 9 | ```shell 10 | gem install influxdb-cli 11 | ``` 12 | 13 | ### Options 14 | 15 | ```shell 16 | $ influxdb-cli help db 17 | 18 | Usage: 19 | influxdb-cli db 20 | 21 | Options: 22 | [--host=HOST] # Hostname 23 | # Default: localhost 24 | [--port=PORT] # Port 25 | # Default: 8086 26 | -u, [--username=USERNAME] # Username 27 | # Default: root 28 | -p, [--password=PASSWORD] # Password 29 | # Default: root 30 | -d, [--database=DATABASE] # Database 31 | # Default: db 32 | [--pretty=PRETTY] # Human readable times (UTC) 33 | [--ssl], [--no-ssl] # Connect using TLS/SSL 34 | [--time-precision=TIME_PRECISION] # Time precision can be set to either "s" for seconds, "ms" for milliseconds, or "u" for microseconds 35 | # Default: s 36 | ``` 37 | 38 | ### Usage 39 | 40 | #### Connect to a database 41 | 42 | ```shell 43 | $ influxdb-cli 44 | Connecting to {"host"=>"localhost", "port"=>8086, "username"=>"root", "password"=>"root", "database"=>"db"} 45 | ✔ ready 46 | ``` 47 | 48 | or 49 | 50 | ```shell 51 | $ influxdb-cli -u user -p password -d database --host sandbox.influxdb.org --port 9061 52 | Connecting to {"host"=>"sandbox.influxdb.org", "port"=>"9061", "username"=>"username", "password"=>"password", "database"=>"database"} 53 | ✔ ready 54 | ``` 55 | 56 | [InfluxDB Playground](http://play.influxdb.org) :metal: 57 | 58 | #### Create a database and user 59 | 60 | ```ruby 61 | 2.0.0 (main)> db.create_database 'db' 62 | 2.0.0 (main)> db.create_database_user 'db', 'root', 'root' 63 | ``` 64 | 65 | #### List databases 66 | 67 | ```ruby 68 | 2.0.0 (main)> db.list_databases 69 | ``` 70 | 71 | #### Switch databases 72 | 73 | ```ruby 74 | 2.0.0 (main)> use other_database 75 | 2.0.0 (main)> db.database 76 | => "other_database" 77 | ``` 78 | 79 | #### Write a point 80 | 81 | ```ruby 82 | 2.0.0 (main)> db.write_point('tests', { message: 'Hello Pablo' }) 83 | 84 | 2.0.0 (main)> SELECT * FROM tests 85 | 86 | +---------------+-----------------+-------------+ 87 | | tests | 88 | +---------------+-----------------+-------------+ 89 | | time | sequence_number | message | 90 | +---------------+-----------------+-------------+ 91 | | 1387287723816 | 1 | Hello Pablo | 92 | +---------------+-----------------+-------------+ 93 | 1 result found for tests 94 | 95 | Query duration: 0.0s 96 | ``` 97 | 98 | #### Return the last point from every time series in the database 99 | 100 | ```ruby 101 | 2.0.0 (main)> SELECT * FROM /.*/ LIMIT 1 102 | ``` 103 | 104 | or to get only the name from every time series in the database. 105 | 106 | ```ruby 107 | 2.0.0 (main)> db.query('SELECT * FROM /.*/ LIMIT 1').keys 108 | => [ 109 | [0] "tests", 110 | [1] "response_times", 111 | [2] "deploys", 112 | [3] "..." 113 | ] 114 | ``` 115 | 116 | 117 | #### Query with a [tabularized output](https://github.com/visionmedia/terminal-table) 118 | 119 | ```ruby 120 | 2.0.0 (main)> SELECT * FROM deploys 121 | +---------------+-----------------+-----------------+--------+-----------------+-------------------+----------+ 122 | | deploys | 123 | +---------------+-----------------+-----------------+--------+-----------------+-------------------+----------+ 124 | | time | sequence_number | application | branch | latest_revision | previous_revision | stage | 125 | +---------------+-----------------+-----------------+--------+-----------------+-------------------+----------+ 126 | | ... | ... | ... | ... | ... | ... | ... | 127 | +---------------+-----------------+-----------------+--------+-----------------+-------------------+----------+ 128 | 129 | 1 result found for deploys 130 | 131 | Query duration: 0.49s 132 | ``` 133 | 134 | #### Query with a [Ruby Hash output](https://github.com/michaeldv/awesome_print) 135 | 136 | ```ruby 137 | 2.0.0 (main)> db.query('SELECT * FROM deploys') 138 | => { 139 | "deploys" => [ 140 | [ 0] { 141 | "time" => "...", 142 | "sequence_number" => "...", 143 | "application" => "...", 144 | "branch" => "...", 145 | "latest_revision" => "...", 146 | "previous_revision" => "...", 147 | "stage" => "..." 148 | }, 149 | ``` 150 | 151 | #### Other methods 152 | 153 | ```ruby 154 | 2.0.0 (main)> db.write_point(name, data) 155 | 2.0.0 (main)> db.list_databases 156 | 2.0.0 (main)> ls -q db 157 | InfluxDB::Client#methods: 158 | _write create_database database= delete_database_user get_database_user_list password port= queue= username 159 | alter_database_privilege create_database_user delete_cluster_admin get_cluster_admin_list host password= query update_cluster_admin username= 160 | create_cluster_admin database delete_database list_databases host= port queue update_database_user write_point 161 | instance variables: @database @host @http @password @port @queue @username 162 | ``` 163 | 164 | ### Pry commands 165 | 166 | As influxdb-cli is empowered with Pry, all Pry awesome commands are available in the console. 167 | 168 | #### show-source 169 | 170 | ```ruby 171 | 2.0.0 (main)> show-source InfluxDB::Client#query 172 | 173 | From: /Users/pablo/.gem/ruby/2.0.0/gems/influxdb-0.0.11/lib/influxdb/client.rb @ line 152: 174 | Owner: InfluxDB::Client 175 | Visibility: public 176 | Number of lines: 17 177 | 178 | def query(query) 179 | url = full_url("db/#{@database}/series", "q=#{query}") 180 | url = URI.encode url 181 | response = @http.request(Net::HTTP::Get.new(url)) 182 | series = JSON.parse(response.body) 183 | 184 | if block_given? 185 | series.each { |s| yield s['name'], denormalize_series(s) } 186 | else 187 | series.reduce({}) do |col, s| 188 | name = s['name'] 189 | denormalized_series = denormalize_series s 190 | col[name] = denormalized_series 191 | col 192 | end 193 | end 194 | end 195 | ``` 196 | 197 | #### show-doc 198 | 199 | ```ruby 200 | 201 | 2.0.0 (main)> show-doc InfluxDB::Client#initialize 202 | 203 | From: /Users/pablo/.gem/ruby/2.0.0/gems/influxdb-0.0.11/lib/influxdb/client.rb @ line 13: 204 | Owner: InfluxDB::Client 205 | Visibility: private 206 | Signature: initialize(*args) 207 | Number of lines: 20 208 | 209 | Initializes a new Influxdb client 210 | 211 | === Examples: 212 | 213 | Influxdb.new # connect to localhost using root/root 214 | # as the credentials and doesn't connect to a db 215 | 216 | Influxdb.new 'db' # connect to localhost using root/root 217 | # as the credentials and 'db' as the db name 218 | 219 | Influxdb.new :username => 'username' # override username, other defaults remain unchanged 220 | 221 | Influxdb.new 'db', :username => 'username' # override username, use 'db' as the db name 222 | 223 | === Valid options in hash 224 | 225 | +:hostname+:: the hostname to connect to 226 | +:port+:: the port to connect to 227 | +:username+:: the username to use when executing commands 228 | +:password+:: the password associated with the username 229 | ``` 230 | 231 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | -------------------------------------------------------------------------------- /bin/influxdb-cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # encoding: utf-8 3 | 4 | require 'rubygems' 5 | require 'influxdb' 6 | require 'pry' 7 | require 'thor' 8 | require 'awesome_print' 9 | 10 | $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib') 11 | 12 | require 'influxdb_client/version' 13 | require 'influxdb_client/client' 14 | 15 | class InfluxDBClientTasks < Thor 16 | @@db = nil 17 | 18 | desc 'db', 'Connect to InfluxDB (default command)' 19 | method_option :host, default: 'localhost', desc: 'Hostname' 20 | method_option :port, default: 8086, desc: 'Port' 21 | method_option :username, default: 'root', desc: 'Username', aliases: '-u' 22 | method_option :password, default: 'root', desc: 'Password', aliases: '-p' 23 | method_option :database, default: 'db', desc: 'Database', aliases: '-d' 24 | method_option :pretty, default: nil, desc: 'Human readable times (UTC)' 25 | method_option :ssl, default: false, desc: 'Connect using TLS/SSL', type: :boolean 26 | method_option :time_precision, default: 's', desc: 'Time precision can be set to either "s" for seconds, "ms" for milliseconds, or "u" for microseconds' 27 | 28 | def db 29 | puts "Connecting to #{options.inspect}" 30 | @@db ||= InfluxDB::Client.new options[:database], 31 | { 32 | username: options[:username], 33 | password: options[:password], 34 | host: options[:host], 35 | port: options[:port], 36 | use_ssl: options[:ssl], 37 | time_precision: options[:time_precision] 38 | } 39 | InfluxDBClient::Client.pretty = options[:pretty] 40 | puts '✔ ready' 41 | end 42 | 43 | desc 'version', 'Show influxdb-cli version' 44 | def version 45 | puts "influxdb-cli #{InfluxDBClient::VERSION}" 46 | end 47 | 48 | def self.db; @@db; end 49 | 50 | default_command :db 51 | end 52 | 53 | # Returns {InfluxDB::Client} instance using given parameters. 54 | # 55 | # @return [InfluxDB::Client] 56 | def db; InfluxDBClientTasks.db; end 57 | 58 | InfluxDBClientTasks.start 59 | 60 | # exit if the db command wasn't called 61 | exit 0 unless db 62 | 63 | 64 | # allow typing queries directly from console i.e.`select * from deploys` instead of `query('select * from deploys')`. 65 | # matches `delete from ...` and `select ... from ...` 66 | Pry::Commands.block_command InfluxDBClient::Client::QUERY_LANGUAGE_MATCHER, 'Execute a query' do |query| 67 | start = Time.now 68 | result = db.query(query) 69 | duration = Time.now - start 70 | 71 | InfluxDBClient::Client.print_tabularize(result, db.time_precision) 72 | 73 | # print query duration in seconds 74 | puts "Query duration: #{duration.round(2)}s" 75 | end 76 | 77 | # switch databases `use db_name` 78 | Pry::Commands.block_command InfluxDBClient::Client::SWITCH_DATABASE_MATCHER, 'Switch databases' do |db_name| 79 | db.database = db_name 80 | end 81 | 82 | # awesome_print 83 | Pry.config.print = proc { |output, value| Pry::Helpers::BaseHelpers.stagger_output("=> #{value.ai}", output) } 84 | 85 | # TODO start `pry` only in case of `db` command, `help` and `version` should not start `pry` 86 | pry 87 | -------------------------------------------------------------------------------- /influxdb-cli.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), %w[lib influxdb_client version])) 4 | 5 | Gem::Specification.new do |gem| 6 | gem.name = 'influxdb-cli' 7 | gem.version = InfluxDBClient::VERSION 8 | gem.authors = ['Pablo Cantero'] 9 | gem.email = ['pablo@pablocantero.com'] 10 | gem.description = %q{Ruby CLI for InfluxDB} 11 | gem.summary = %q{Ruby CLI for InfluxDB} 12 | gem.homepage = 'https://github.com/phstc/influxdb-cli' 13 | 14 | gem.files = `git ls-files`.split($/) 15 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 16 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 17 | gem.require_paths = ['lib'] 18 | 19 | gem.add_dependency 'influxdb' 20 | gem.add_dependency 'pry' 21 | gem.add_dependency 'thor', '~> 0.18.1' 22 | gem.add_dependency 'awesome_print' 23 | gem.add_dependency 'terminal-table' 24 | 25 | gem.add_development_dependency 'rspec' 26 | gem.add_development_dependency 'bundler' 27 | gem.add_development_dependency 'rake' 28 | end 29 | 30 | -------------------------------------------------------------------------------- /lib/influxdb_client.rb: -------------------------------------------------------------------------------- 1 | require 'influxdb_client/version' 2 | require 'influxdb_client/client' 3 | 4 | module InfluxDBClient 5 | end 6 | 7 | -------------------------------------------------------------------------------- /lib/influxdb_client/client.rb: -------------------------------------------------------------------------------- 1 | require 'terminal-table' 2 | 3 | module InfluxDBClient 4 | class Client 5 | QUERY_LANGUAGE_MATCHER = /\A\s*((delete\s+from|select\s+.+\s+from)\s.+)\z/i 6 | SWITCH_DATABASE_MATCHER = /\A\s*use\s+(\S+)\s*\z/i 7 | 8 | # Prints a tabularized output from a query result. 9 | # 10 | # @param result [Hash] the {InfluDB::Client#query result} 11 | # @param output [STDOUT] the output to `puts` the results 12 | # @return [Hash] the number of points per time series i.e. { 'response_times.count' => 10 } 13 | def self.print_tabularize(result, time_precision, output=$stdout) 14 | result ||= {} 15 | 16 | if result.keys.empty? 17 | output.puts 'No results found' 18 | return 19 | end 20 | 21 | result.keys.each do |series| 22 | result_series = result[series] 23 | if result_series.any? 24 | output.puts generate_table(series, result_series, time_precision) 25 | output.puts "#{result_series.size} " \ 26 | "#{pluralize(result_series.size, 'result')} " \ 27 | "found for #{series}" 28 | else 29 | output.puts "No results found for #{series}" 30 | end 31 | # print a line break between time series output 32 | output.puts 33 | end 34 | end 35 | 36 | def self.pretty=(pretty) 37 | @pretty = !!pretty 38 | end 39 | 40 | private 41 | 42 | def self.pluralize(count, singular, plural = nil) 43 | if count > 1 44 | plural ? plural : "#{singular}s" 45 | else 46 | singular 47 | end 48 | end 49 | 50 | def self.generate_table(series, result_series, time_precision) 51 | headings = result_series.first.keys 52 | precision_factor, str_format = case time_precision.to_s 53 | when 's' then [1.0, '%F %T'] 54 | when 'ms' then [1_000.0, '%F %T.%3N'] 55 | when 'u' then [1_000_000.0, '%F %T.%6N'] 56 | else raise "unknown time_precision #{time_precision}" 57 | end 58 | rows = result_series.map do |row| 59 | if @pretty 60 | seconds_with_frac = row['time'].to_f / precision_factor 61 | row['time'] = Time.at(seconds_with_frac).utc.strftime(str_format) 62 | end 63 | row.values 64 | end 65 | 66 | Terminal::Table.new title: series, headings: headings, rows: rows 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /lib/influxdb_client/version.rb: -------------------------------------------------------------------------------- 1 | module InfluxDBClient 2 | VERSION = '0.1.4' 3 | end 4 | -------------------------------------------------------------------------------- /spec/influxdb_client/client_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module InfluxDBClient 4 | describe Client do 5 | describe '.QUERY_LANGUAGE_MATCHER' do 6 | subject { Client::QUERY_LANGUAGE_MATCHER } 7 | context 'when SELECT queries' do 8 | it { should match('SELECT value1, value2 FROM response_times') } 9 | it { should match('select * from response_times') } 10 | it { should match('SELECT * FROM series1, series2') } 11 | it { should match('SELECT * FROM series1, series2 LIMIT 1') } 12 | 13 | it { should_not match('SELECT value1, value2FROM response_times') } 14 | it { should_not match('select from response_times') } 15 | it { should_not match('SELECT * FROM') } 16 | end 17 | 18 | context 'when DELETE queries' do 19 | it { should match('DELETE FROM response_times') } 20 | it { should match('delete from series1, series2') } 21 | 22 | it { should_not match('DELETEFROM response_times') } 23 | it { should_not match('delete value1, value2 from series1, series2') } 24 | it { should_not match('DELETE * FROM series1, series2') } 25 | end 26 | end 27 | 28 | describe '.SWITCH_DATABASE_MATCHER' do 29 | subject { Client::SWITCH_DATABASE_MATCHER } 30 | it { should match('use response_times') } 31 | it { should match(' use response_times ') } 32 | 33 | it { should_not match('use') } 34 | it { should_not match(' use ') } 35 | it { should_not match('use response_times tests') } 36 | it { should_not match('useresponse_times') } 37 | end 38 | 39 | describe '.print_tabularize' do 40 | let(:result) { { series1: [{ 'time' => 1387287723816, 'value1' => 1, 'value2' => 2 }], 41 | series2: [{ 'time' => 1394552447955, 'value3' => 3, 'value4' => 4, 'value5' => nil, 'value6' => nil }, 42 | { 'time' => 1394664358980, 'value3' => nil, 'value4' => 4, 'value5' => 5, 'value6' => 6 }] } } 43 | 44 | it 'generates tables' do 45 | expect(Terminal::Table).to receive(:new). 46 | with(title: :series1, headings: %w[time value1 value2], rows: [[1387287723816, 1, 2]]) 47 | 48 | expect(Terminal::Table).to receive(:new). 49 | with(title: :series2, headings: %w[time value3 value4 value5 value6], rows: [[1394552447955, 3, 4, nil, nil], [1394664358980, nil, 4, 5, 6]]) 50 | 51 | described_class.print_tabularize(result, :ms) 52 | end 53 | 54 | context 'when pretty' do 55 | before(:all) { described_class.pretty = true } 56 | after(:all) { described_class.pretty = false } 57 | 58 | context 'and time precision is seconds' do 59 | let(:result) { { series1: [{ 'time' => 1387287723, 'value1' => 1, 'value2' => 2 }] } } 60 | it 'generates tables' do 61 | expect(Terminal::Table).to receive(:new). 62 | with(title: :series1, headings: %w[time value1 value2], rows: [['2013-12-17 13:42:03', 1, 2]]) 63 | 64 | described_class.print_tabularize(result, :s) 65 | end 66 | end 67 | 68 | context 'and time precision is milliseconds' do 69 | it 'generates tables' do 70 | expect(Terminal::Table).to receive(:new). 71 | with(title: :series1, headings: %w[time value1 value2], rows: [['2013-12-17 13:42:03.815', 1, 2]]) 72 | 73 | expect(Terminal::Table).to receive(:new). 74 | with(title: :series2, headings: %w[time value3 value4 value5 value6], rows: [['2014-03-11 15:40:47.954', 3, 4, nil, nil], ['2014-03-12 22:45:58.980', nil, 4, 5, 6]]) 75 | 76 | described_class.print_tabularize(result, :ms) 77 | end 78 | end 79 | 80 | context 'and time precision is microseconds' do 81 | let(:result) { { series1: [{ 'time' => 1387287723816232, 'value1' => 1, 'value2' => 2 }] } } 82 | it 'generates tables' do 83 | expect(Terminal::Table).to receive(:new). 84 | with(title: :series1, headings: %w[time value1 value2], rows: [['2013-12-17 13:42:03.816231', 1, 2]]) 85 | 86 | described_class.print_tabularize(result, :u) 87 | end 88 | end 89 | 90 | end 91 | 92 | it 'prints results' do 93 | output = double 'Output' 94 | table = double 'Table' 95 | allow(Terminal::Table).to receive(:new).and_return(table) 96 | 97 | # should print series1 and series2 98 | expect(output).to receive(:puts).twice.with(table) 99 | # print results count 100 | expect(output).to receive(:puts).once.with('1 result found for series1') 101 | expect(output).to receive(:puts).once.with('2 results found for series2') 102 | # line break for series 103 | expect(output).to receive(:puts).twice.with(no_args) 104 | 105 | described_class.print_tabularize(result, :ms, output) 106 | end 107 | 108 | context 'when no results' do 109 | let(:result) { { series1: [{ value1: 1, value2: 2 }], 110 | series2: [] } } 111 | 112 | it 'prints generic no results found' do 113 | output = double 'Output' 114 | result = {} 115 | expect(output).to receive(:puts).once.with('No results found') 116 | described_class.print_tabularize(result, :ms, output) 117 | end 118 | 119 | it 'prints specific no results found per series' do 120 | output = double 'Output' 121 | table = double 'Table' 122 | allow(Terminal::Table).to receive(:new).and_return(table) 123 | 124 | # should print series1 125 | expect(output).to receive(:puts).once.with(table) 126 | # print results count 127 | expect(output).to receive(:puts).once.with('1 result found for series1') 128 | # no results for series 2 129 | expect(output).to receive(:puts).once.with('No results found for series2') 130 | # line break for series 131 | expect(output).to receive(:puts).twice.with(no_args) 132 | 133 | described_class.print_tabularize(result, :ms, output) 134 | end 135 | end 136 | 137 | context 'when result is null' do 138 | it 'prints generic no results found' do 139 | output = double 'Output' 140 | result = nil 141 | expect(output).to receive(:puts).once.with('No results found') 142 | described_class.print_tabularize(result, :ms, output) 143 | end 144 | end 145 | end 146 | end 147 | end 148 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | require 'fileutils' 3 | require 'tempfile' 4 | 5 | Dir['../lib/**/*.rb'].each &method(:require) 6 | 7 | require './lib/influxdb_client' 8 | 9 | RSpec.configure do |config| 10 | original_stderr = $stderr 11 | original_stdout = $stdout 12 | 13 | config.before(:all) do 14 | # Redirect stderr and stdout 15 | $stderr = File.new('/dev/null', 'w') 16 | $stdout = File.new('/dev/null', 'w') 17 | end 18 | 19 | config.after(:all) do 20 | $stderr = original_stderr 21 | $stdout = original_stdout 22 | end 23 | end 24 | 25 | --------------------------------------------------------------------------------