indy 0.4.0.pre → 0.5.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.
@@ -19,7 +19,7 @@ class Indy
19
19
  @entry_regexp = Regexp.new(params_hash[:entry_regexp])
20
20
  end
21
21
  @entry_fields = params_hash[:entry_fields]
22
- @time_format = params_hash[:time_format]
22
+ @time_format = params_hash[:time_format] || Indy::LogFormats::DEFAULT_DATE_TIME # '%Y-%m-%d %H:%M:%S'
23
23
  define_struct
24
24
  end
25
25
 
@@ -27,6 +27,7 @@ class Indy
27
27
  params_hash = {}
28
28
  params_hash[:entry_regexp] = Indy::LogFormats::DEFAULT_ENTRY_REGEXP
29
29
  params_hash[:entry_fields] = Indy::LogFormats::DEFAULT_ENTRY_FIELDS
30
+ params_hash[:time_format] = Indy::LogFormats::DEFAULT_DATE_TIME
30
31
  params_hash
31
32
  end
32
33
 
@@ -54,7 +55,7 @@ class Indy
54
55
  end
55
56
 
56
57
  #
57
- # Define Struct::Entry with the fields from @log_definition. Ignore warnings.
58
+ # Define Struct::Entry. Ignore warnings.
58
59
  #
59
60
  def define_struct
60
61
  fields = (@entry_fields + [:raw_entry]).sort_by{|key|key.to_s}
@@ -85,13 +86,14 @@ class Indy
85
86
  match_data = /#{@entry_regexp}/.match(raw_entry)
86
87
  return nil unless match_data
87
88
  values = match_data.captures
89
+ values.shift if @multiline
88
90
  entry_hash([raw_entry, values].flatten)
89
91
  end
90
92
 
91
93
  #
92
94
  # Return a hash of field=>value pairs for the array of captured values from a log entry
93
95
  #
94
- # @param [Array] capture_array The array of values captured by the @log_definition.entry_regexp
96
+ # @param [Array] capture_array The array of values captured by the LogDefinition regexp
95
97
  #
96
98
  def parse_entry_captures( capture_array )
97
99
  entire_entry = capture_array.shift
@@ -106,7 +108,7 @@ class Indy
106
108
  if values.length == @entry_fields.length + 1 # values also includes raw_entry
107
109
  @field_list_is_valid = true
108
110
  else
109
- raise ArgumentError, "Field mismatch between log pattern and log data. The data is: '#{values.join(':::')}'"
111
+ raise Indy::Source::FieldMismatchException, "Number of expected fields does not match those captured via the regexp pattern.\nThe expected fields are:\n=> #{@entry_fields.join("\n=> ")}\nThe log entry and captured fields are:\n=> #{values.join("\n=> ")}"
110
112
  end
111
113
  end
112
114
 
@@ -17,17 +17,18 @@ class Indy
17
17
  NUMBER_REGEXP = '(\d+)'
18
18
  DQUOTE_DELIM_REGEXP = '"([^"]+)"'
19
19
 
20
- DEFAULT_DATE_TIME = '\d{4}.\d{2}.\d{2}\s+\d{2}.\d{2}.\d{2}' #"%Y-%m-%d %H:%M:%S"
20
+ DEFAULT_DATE_TIME = '\d{4}.\d{2}.\d{2}\s+\d{2}.\d{2}.\d{2}' # "%Y-%m-%d %H:%M:%S"
21
21
  DEFAULT_SEVERITY = [:trace,:debug,:info,:warn,:error,:fatal]
22
22
  DEFAULT_SEVERITY_PATTERN = "(?:#{DEFAULT_SEVERITY.map{|s| s.to_s.upcase}.join("|")})"
23
23
  DEFAULT_APPLICATION = '\w+'
24
24
  DEFAULT_MESSAGE = '.+'
25
25
 
26
- DEFAULT_ENTRY_FIELDS = [:time,:severity,:application,:message]
26
+ DEFAULT_ENTRY_FIELDS = [:time, :severity, :application, :message]
27
27
  DEFAULT_ENTRY_REGEXP = /^(#{DEFAULT_DATE_TIME})\s+(#{DEFAULT_SEVERITY_PATTERN})\s+(#{DEFAULT_APPLICATION})\s+-\s+(#{DEFAULT_MESSAGE})$/
28
28
 
29
29
  COMMON_FIELDS = [:host, :ident, :authuser, :time, :request, :status, :bytes]
30
30
  COMMON_REGEXP = /^#{IPV4_REGEXP} #{SPACE_DELIM_REGEXP} #{SPACE_DELIM_REGEXP} #{BRACKET_DELIM_REGEXP} #{DQUOTE_DELIM_REGEXP} #{HTTP_STATUS_REGEXP} #{NUMBER_REGEXP}$/
31
+ COMMON_TIME_FORMAT = "%d\/%b\/%Y:%H:%M:%S %z"
31
32
 
32
33
  COMBINED_FIELDS = COMMON_FIELDS + [:referrer, :user_agent]
33
34
  COMBINED_REGEXP = /^#{IPV4_REGEXP} #{SPACE_DELIM_REGEXP} #{SPACE_DELIM_REGEXP} #{BRACKET_DELIM_REGEXP} #{DQUOTE_DELIM_REGEXP} #{HTTP_STATUS_REGEXP} #{NUMBER_REGEXP} #{DQUOTE_DELIM_REGEXP} #{DQUOTE_DELIM_REGEXP}$/
@@ -42,7 +43,7 @@ class Indy
42
43
  #
43
44
  # Indy default log format
44
45
  # e.g.:
45
- # INFO 2000-09-07 MyApp - Entering APPLICATION.
46
+ # 2000-09-07 INFO MyApp - Entering APPLICATION.
46
47
  #
47
48
  DEFAULT_LOG_FORMAT = {:entry_regexp => LogFormats::DEFAULT_ENTRY_REGEXP, :entry_fields => LogFormats::DEFAULT_ENTRY_FIELDS}
48
49
 
@@ -59,11 +60,11 @@ class Indy
59
60
  #
60
61
  # NCSA Common Log Format log format
61
62
  #
62
- COMMON_LOG_FORMAT = {:entry_regexp => LogFormats::COMMON_REGEXP, :entry_fields => LogFormats::COMMON_FIELDS}
63
+ COMMON_LOG_FORMAT = {:entry_regexp => LogFormats::COMMON_REGEXP, :entry_fields => LogFormats::COMMON_FIELDS, :time_format => LogFormats::COMMON_TIME_FORMAT}
63
64
 
64
65
  #
65
66
  # NCSA Combined Log Format log format
66
67
  #
67
- COMBINED_LOG_FORMAT = {:entry_regexp => LogFormats::COMBINED_REGEXP, :entry_fields => LogFormats::COMBINED_FIELDS}
68
+ COMBINED_LOG_FORMAT = {:entry_regexp => LogFormats::COMBINED_REGEXP, :entry_fields => LogFormats::COMBINED_FIELDS, :time_format => LogFormats::COMMON_TIME_FORMAT}
68
69
 
69
70
  end
@@ -3,11 +3,10 @@ class Indy
3
3
  class Search
4
4
 
5
5
  attr_accessor :source
6
- attr_accessor :log_definition
7
6
 
8
7
  attr_accessor :start_time, :end_time, :inclusive
9
8
 
10
- def initialize(params_hash)
9
+ def initialize(params_hash={})
11
10
  while (param = params_hash.shift) do
12
11
  send("#{param.first}=",param.last)
13
12
  end
@@ -25,7 +24,7 @@ class Indy
25
24
  results = []
26
25
  results += search do |entry|
27
26
  if type == :all || is_match?(type,entry,search_criteria)
28
- result_struct = @log_definition.create_struct(entry)
27
+ result_struct = @source.log_definition.create_struct(entry)
29
28
  if block_given?
30
29
  block.call(result_struct)
31
30
  else
@@ -38,12 +37,12 @@ class Indy
38
37
 
39
38
  #
40
39
  # Search the @source and yield to the block the entry that was found
41
- # with @log_definition
40
+ # with the LogDefinition
42
41
  #
43
42
  # This method is supposed to be used internally.
44
43
  #
45
44
  def search(&block)
46
- if @log_definition.multiline
45
+ if @source.log_definition.multiline
47
46
  multiline_search(&block)
48
47
  else
49
48
  standard_search(&block)
@@ -58,9 +57,9 @@ class Indy
58
57
  results = []
59
58
  source_lines = (is_time_search ? @source.open([@start_time,@end_time]) : @source.open)
60
59
  source_lines.each do |single_line|
61
- hash = @log_definition.parse_entry(single_line)
60
+ hash = @source.log_definition.parse_entry(single_line)
62
61
  next unless hash
63
- next unless Indy::Time.inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
62
+ next unless inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
64
63
  results << (block.call(hash) if block_given?)
65
64
  end
66
65
  results.compact
@@ -72,10 +71,10 @@ class Indy
72
71
  def multiline_search(&block)
73
72
  is_time_search = use_time_criteria?
74
73
  source_io = StringIO.new( (is_time_search ? @source.open([@start_time,@end_time]) : @source.open ).join("\n") )
75
- results = source_io.read.scan(@log_definition.entry_regexp).collect do |entry|
76
- hash = @log_definition.parse_entry_captures(entry)
74
+ results = source_io.read.scan(@source.log_definition.entry_regexp).collect do |entry|
75
+ hash = @source.log_definition.parse_entry_captures(entry)
77
76
  next unless hash
78
- next unless Indy::Time.inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
77
+ next unless inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
79
78
  block.call(hash) if block_given?
80
79
  end
81
80
  results.compact
@@ -87,8 +86,8 @@ class Indy
87
86
  def use_time_criteria?
88
87
  if @start_time || @end_time
89
88
  # ensure both boundaries are set
90
- @start_time ||= Indy::Time.forever_ago(@log_definition.time_format)
91
- @end_time ||= Indy::Time.forever(@log_definition.time_format)
89
+ @start_time ||= Indy::Time.forever_ago(@source.log_definition.time_format)
90
+ @end_time ||= Indy::Time.forever(@source.log_definition.time_format)
92
91
  end
93
92
  @start_time && @end_time
94
93
  end
@@ -114,8 +113,8 @@ class Indy
114
113
  if params_hash[:time]
115
114
  time_scope_from_direction(params_hash[:direction], params_hash[:span], params_hash[:time])
116
115
  else
117
- @start_time = Indy::Time.parse_date(params_hash[:start_time]) if params_hash[:start_time]
118
- @end_time = Indy::Time.parse_date(params_hash[:end_time]) if params_hash[:end_time]
116
+ @start_time = Indy::Time.parse_date(params_hash[:start_time], @source.log_definition.time_format) if params_hash[:start_time]
117
+ @end_time = Indy::Time.parse_date(params_hash[:end_time], @source.log_definition.time_format) if params_hash[:end_time]
119
118
  end
120
119
  @inclusive = params_hash[:inclusive]
121
120
  end
@@ -124,7 +123,7 @@ class Indy
124
123
  # Parse direction, span, and time to set @start_time and @end_time
125
124
  #
126
125
  def time_scope_from_direction(direction, span, time)
127
- time = Indy::Time.parse_date(time)
126
+ time = Indy::Time.parse_date(time, @source.log_definition.time_format)
128
127
  span = (span.to_i * 60).seconds if span
129
128
  if direction == :before
130
129
  @end_time = time
@@ -142,6 +141,19 @@ class Indy
142
141
  @inclusive = @start_time = @end_time = nil
143
142
  end
144
143
 
145
- end
144
+ #
145
+ # Evaluate if a log entry satisfies the configured time conditions
146
+ #
147
+ def inside_time_window?(time_string,start_time,end_time,inclusive)
148
+ time = Indy::Time.parse_date(time_string, @source.log_definition.time_format)
149
+ return false unless time
150
+ if inclusive
151
+ return true unless (time > end_time || time < start_time)
152
+ else
153
+ return true unless (time >= end_time || time <= start_time)
154
+ end
155
+ return false
156
+ end
146
157
 
158
+ end
147
159
  end
@@ -5,6 +5,12 @@ class Indy
5
5
  #
6
6
  class Source
7
7
 
8
+ # Exception raised when entry regexp does not match data
9
+ class FieldMismatchException < Exception; end
10
+
11
+ # log definition
12
+ attr_accessor :log_definition
13
+
8
14
  # log source type. :cmd, :file, or :string
9
15
  attr_reader :type
10
16
 
@@ -14,9 +20,6 @@ class Indy
14
20
  # the StringIO object
15
21
  attr_reader :io
16
22
 
17
- # log definition
18
- attr_reader :log_definition
19
-
20
23
  # Exception raised when unable to open source
21
24
  class Invalid < Exception; end
22
25
 
@@ -27,7 +30,7 @@ class Indy
27
30
  #
28
31
  def initialize(param,log_definition=nil)
29
32
  raise Indy::Source::Invalid, "No source specified." if param.nil?
30
- @log_definition = log_definition || LogDefinition.new()
33
+ self.log_definition = log_definition || LogDefinition.new()
31
34
  return discover_connection(param) unless param.respond_to?(:keys)
32
35
  if param[:cmd]
33
36
  set_connection(:cmd, param[:cmd])
@@ -155,7 +158,20 @@ class Indy
155
158
  # Return the time of a log entry index, with an optional offset
156
159
  #
157
160
  def time_at(index, delta=0)
158
- ::Time.parse(@entries[index + delta])
161
+ begin
162
+ entry = @entries[index + delta]
163
+ time = @log_definition.parse_entry(entry)[:time]
164
+ result = Indy::Time.parse_date(time, @log_definition.time_format)
165
+ rescue FieldMismatchException => fme
166
+ raise
167
+ rescue Exception => e
168
+ msg = "Unable to parse time from entry. Time value was #{time.inspect}. Original exception was:\n#{e.class}\n"
169
+ raise Indy::Time::ParseException, msg + e.message
170
+ end
171
+ if result.nil?
172
+ raise Indy::Time::ParseException, "Unable to parse datetime. Raw value was #{time.inspect}. Entry was #{entry}."
173
+ end
174
+ result
159
175
  end
160
176
 
161
177
  #
@@ -1,38 +1,35 @@
1
+ require 'active_support'
1
2
  require 'active_support/core_ext'
2
3
 
3
4
  class Indy
4
5
 
5
6
  class Time
6
7
 
8
+ # Exception raised when unable to parse an entry's time value
9
+ class ParseException < Exception; end
10
+
7
11
  class << self
8
12
 
9
13
  #
10
14
  # Return a valid DateTime object for the log entry string or hash
11
15
  #
12
- # @param [String, Hash] param The log entry string or hash
16
+ # @param [String, Hash] time The log entry string or hash
17
+ #
18
+ # @param [String] time_format String of #strftime directives to define format
13
19
  #
14
20
  def parse_date(time,time_format=nil)
15
21
  return time if time.kind_of? ::Time or time.kind_of? DateTime
16
22
  if time_format
17
23
  begin
18
- # Attempt the appropriate parse method
19
24
  DateTime.strptime(time, time_format)
20
25
  rescue
21
- # If appropriate, fall back to simple parse method
22
26
  DateTime.parse(time) rescue nil
23
27
  end
24
28
  else
25
29
  begin
26
- # If appropriate, fall back to simple parse method
27
30
  ::Time.parse(time)
28
31
  rescue => e
29
32
  raise "Failed to create time object. The error was: #{e.message}"
30
- #begin
31
- # # one last try!!
32
- # DateTime.parse(time)
33
- #rescue Exception => e
34
- # raise "Failed to create time object. The error was: #{e.message}"
35
- #end
36
33
  end
37
34
  end
38
35
  end
@@ -56,23 +53,6 @@ class Indy
56
53
  end
57
54
  end
58
55
 
59
- #
60
- # Evaluate if a log entry satisfies the configured time conditions
61
- #
62
- # @param [Hash] entry_hash The log entry's hash
63
- #
64
- def inside_time_window?(time_string,start_time,end_time,inclusive)
65
- time = Indy::Time.parse_date(time_string)
66
- #return false unless time && entry_hash
67
- if inclusive
68
- true unless time > end_time or time < start_time
69
- else
70
- true unless time >= end_time or time <= start_time
71
- end
72
- end
73
-
74
56
  end
75
-
76
57
  end
77
-
78
58
  end
@@ -1,7 +1,7 @@
1
1
 
2
2
  class Indy
3
3
 
4
- VERSION = '0.4.0.pre'
4
+ VERSION = '0.5.0'
5
5
 
6
6
  def self.show_version_changes(version)
7
7
  date = ""
@@ -12,12 +12,12 @@ describe 'Indy' do
12
12
  end
13
13
 
14
14
  it "#last_entries should return an array of Struct::Entry object" do
15
- @indy.send(:last_entries, 2).class.should == Array
16
- @indy.send(:last_entries, 2).first.class.should == Struct::Entry
15
+ expect(@indy.send(:last_entries, 2).class).to eq(Array)
16
+ expect(@indy.send(:last_entries, 2).first.class).to eq(Struct::Entry)
17
17
  end
18
18
 
19
19
  it "#last_entries should return correct Struct::Entry objects" do
20
- @indy.send(:last_entries, 2).first.time.should == '2000-09-07 14:07:43'
20
+ expect(@indy.send(:last_entries, 2).first.time).to eq('2000-09-07 14:07:43')
21
21
  end
22
22
 
23
23
  end
@@ -7,20 +7,20 @@ describe 'Indy' do
7
7
  it "should accept v0.3.4 initialization params" do
8
8
  indy_obj = Indy.new(:source => "foo\nbar\n").with(Indy::DEFAULT_LOG_FORMAT)
9
9
  search_obj = indy_obj.search
10
- search_obj.log_definition.class.should eq Indy::LogDefinition
11
- search_obj.log_definition.entry_regexp.class.should eq Regexp
12
- search_obj.log_definition.entry_fields.class.should eq Array
10
+ expect(search_obj.source.log_definition.class).to eq Indy::LogDefinition
11
+ expect(search_obj.source.log_definition.entry_regexp.class).to eq Regexp
12
+ expect(search_obj.source.log_definition.entry_fields.class).to eq Array
13
13
  end
14
14
 
15
15
  it "should not raise error with non-conforming data" do
16
16
  @indy = Indy.new(:source => " \nfoobar\n\n baz", :entry_regexp => '([^\s]+) (\w+)', :entry_fields => [:time, :message])
17
- @indy.all.class.should == Array
17
+ expect(@indy.all.class).to eq(Array)
18
18
  end
19
19
 
20
20
  it "should accept time_format parameter" do
21
21
  @indy = Indy.new(:time_format => '%d-%m-%Y', :source => "1-13-2000 yes", :entry_regexp => '^([^\s]+) (\w+)$', :entry_fields => [:time, :message])
22
- @indy.all.class.should == Array
23
- @indy.search.log_definition.time_format.should == '%d-%m-%Y'
22
+ expect(@indy.all.class).to eq(Array)
23
+ expect(@indy.search.source.log_definition.time_format).to eq('%d-%m-%Y')
24
24
  end
25
25
 
26
26
  it "should accept an initialization hash passed to #search" do
@@ -29,8 +29,8 @@ describe 'Indy' do
29
29
  :entry_regexp => '^([^\s]+) (\w+)$',
30
30
  :entry_fields => [:time, :message]}
31
31
  @indy = Indy.search(hash)
32
- @indy.class.should == Indy
33
- @indy.all.length.should == 1
32
+ expect(@indy.class).to eq(Indy)
33
+ expect(@indy.all.length).to eq(1)
34
34
  end
35
35
 
36
36
  end
@@ -47,49 +47,51 @@ describe 'Indy' do
47
47
  context "method" do
48
48
 
49
49
  it "#with should return self" do
50
- @indy.with().class.should == Indy
50
+ expect(@indy.with().class).to eq(Indy)
51
51
  end
52
52
 
53
53
  it "#with should use default log pattern when passed :default" do
54
- @indy.with(:default).all.length.should == 3
54
+ expect(@indy.with(:default).all.length).to eq(3)
55
55
  end
56
56
 
57
- it "should raise ArgumentError when regexp captures don't match fields" do
57
+ it "should raise Exception when regexp captures don't match fields" do
58
58
  log = [ "2000-09-07 14:06:41 INFO MyApp - Entering APPLICATION.",
59
59
  "2000-09-07 14:07:42 DEBUG MyApp - Initializing APPLICATION."].join("\n")
60
- lambda{ Indy.search(log).
61
- with(:entry_regexp => Indy::LogFormats::DEFAULT_ENTRY_REGEXP, :entry_fields => [:field_one]).
62
- all.length.should > 0
63
- }.should raise_error ArgumentError
60
+ expect{
61
+ expect(Indy.search(log).
62
+ with(:entry_regexp => Indy::LogFormats::DEFAULT_ENTRY_REGEXP,
63
+ :entry_fields => [:field_one]
64
+ ).all.length).to be > 0
65
+ }.to raise_error Indy::Source::FieldMismatchException
64
66
  end
65
67
 
66
68
  [:for, :like, :matching].each do |method|
67
69
  it "##{method} should exist" do
68
- @indy.should respond_to(method)
70
+ expect(@indy).to respond_to(method)
69
71
  end
70
72
 
71
73
  it "##{method} should accept a hash of search criteria" do
72
- @indy.send(method,:severity => "INFO").should be_kind_of(Array)
74
+ expect(@indy.send(method,:severity => "INFO")).to be_kind_of(Array)
73
75
  end
74
76
 
75
77
  it "##{method} should return a set of results" do
76
- @indy.send(method,:severity => "DEBUG").should be_kind_of(Array)
78
+ expect(@indy.send(method,:severity => "DEBUG")).to be_kind_of(Array)
77
79
  end
78
80
  end
79
81
 
80
82
  it "#last should return self" do
81
- @indy.last(:span => 1).should be_kind_of Indy
83
+ expect(@indy.last(:span => 1)).to be_kind_of Indy
82
84
  end
83
85
 
84
86
  it "#last should set the time scope to the correct number of minutes" do
85
- @indy.last(:span => 1).all.count.should == 2
87
+ expect(@indy.last(:span => 1).all.count).to eq(2)
86
88
  end
87
89
 
88
90
  it "#last should raise an error if passed an invalid parameter" do
89
- lambda{ @indy.last('a') }.should raise_error( ArgumentError )
90
- lambda{ @indy.last() }.should raise_error( ArgumentError )
91
- lambda{ @indy.last(nil) }.should raise_error( ArgumentError )
92
- lambda{ @indy.last({}) }.should raise_error( ArgumentError )
91
+ expect{ @indy.last('a') }.to raise_error( ArgumentError )
92
+ expect{ @indy.last() }.to raise_error( ArgumentError )
93
+ expect{ @indy.last(nil) }.to raise_error( ArgumentError )
94
+ expect{ @indy.last({}) }.to raise_error( ArgumentError )
93
95
  end
94
96
 
95
97
  end
@@ -98,39 +100,39 @@ describe 'Indy' do
98
100
  context '#search' do
99
101
 
100
102
  it "should be a class method" do
101
- Indy.should respond_to(:search)
103
+ expect(Indy).to respond_to(:search)
102
104
  end
103
105
 
104
106
  it "should accept a string parameter" do
105
- Indy.search("String Log").class.should == Indy
107
+ expect(Indy.search("String Log").class).to eq(Indy)
106
108
  end
107
109
 
108
110
  it "should accept a hash with :cmd key" do
109
- Indy.search(:cmd => "ls").class.should == Indy
111
+ expect(Indy.search(:cmd => "ls").class).to eq(Indy)
110
112
  end
111
113
 
112
114
  it "should accept a hash with :file => filepath" do
113
- Indy.search(:file => "#{File.dirname(__FILE__)}/data.log").all.length.should == 2
115
+ expect(Indy.search(:file => "#{File.dirname(__FILE__)}/data.log").all.length).to eq(2)
114
116
  end
115
117
 
116
118
  it "should accept a hash with :file => File" do
117
- Indy.search(:file => File.open("#{File.dirname(__FILE__)}/data.log")).all.length.should == 2
119
+ expect(Indy.search(:file => File.open("#{File.dirname(__FILE__)}/data.log")).all.length).to eq(2)
118
120
  end
119
121
 
120
122
  it "should accept a valid :source hash" do
121
- Indy.search(:source => {:cmd => 'ls'}).class.should == Indy
123
+ expect(Indy.search(:source => {:cmd => 'ls'}).class).to eq(Indy)
122
124
  end
123
125
 
124
126
  it "should create an instance of Indy::Source in Search object" do
125
- Indy.search("source string").search.source.should be_kind_of(Indy::Source)
127
+ expect(Indy.search("source string").search.source).to be_kind_of(Indy::Source)
126
128
  end
127
129
 
128
130
  it "should raise an exception when passed an invalid source: nil" do
129
- lambda{ Indy.search(nil) }.should raise_error(Indy::Source::Invalid, /No source specified/)
131
+ expect{ Indy.search(nil) }.to raise_error(Indy::Source::Invalid, /No source specified/)
130
132
  end
131
133
 
132
134
  it "should raise an exception when the arity is incorrect" do
133
- lambda{ Indy.search( ) }.should raise_error Indy::Source::Invalid
135
+ expect{ Indy.search( ) }.to raise_error Indy::Source::Invalid
134
136
  end
135
137
 
136
138
  context "with explicit source hash" do
@@ -142,48 +144,46 @@ describe 'Indy' do
142
144
  end
143
145
 
144
146
  it "should attempt open the command" do
145
- IO.stub!(:popen).with('ssh user@system "bash --login -c \"cat /var/log/standard.log\" "')
147
+ allow(IO).to receive(:popen).with('ssh user@system "bash --login -c \"cat /var/log/standard.log\" "')
146
148
  Indy.search(:cmd => 'ssh user@system "bash --login -c \"cat /var/log/standard.log\" "')
147
149
  end
148
150
 
149
151
  it "should not throw an error for an invalid command" do
150
- IO.stub!(:popen).with('an invalid command').and_return('')
151
- Indy.search(:cmd => "an invalid command").class.should == Indy
152
+ allow(IO).to receive(:popen).with('an invalid command').and_return('')
153
+ expect(Indy.search(:cmd => "an invalid command").class).to eq(Indy)
152
154
  end
153
155
 
154
156
  it "should use IO.popen on cmd value" do
155
- IO.stub!(:popen).with("a command").and_return(StringIO.new("2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION."))
156
- Indy.search(:cmd => "a command").for(:application => 'MyApp').length.should == 1
157
+ allow(IO).to receive(:popen).with("a command").and_return(StringIO.new("2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION."))
158
+ expect(Indy.search(:cmd => "a command").for(:application => 'MyApp').length).to eq(1)
157
159
  end
158
160
 
159
161
  it "should handle a real command" do
160
162
  log_file = "data.log"
161
163
  cat_cmd = (is_windows? ? 'type' : 'cat')
162
- Indy.search(:cmd => "#{cat_cmd} #{log_file}").for(:application => 'MyApp').length.should == 2
164
+ expect(Indy.search(:cmd => "#{cat_cmd} #{log_file}").for(:application => 'MyApp').length).to eq(2)
163
165
  end
164
166
 
165
167
  it "should raise Source::Invalid for an invalid command" do
166
- IO.stub!(:popen).with("zzzzzzzzzzzz").and_return('Invalid command')
167
- lambda{ Indy.search(:cmd => "zzzzzzzzzzzz").all }.should raise_error( Indy::Source::Invalid, /Unable to open log source/)
168
+ allow(IO).to receive(:popen).with("zzzzzzzzzzzz").and_return('Invalid command')
169
+ expect{ Indy.search(:cmd => "zzzzzzzzzzzz").all }.to raise_error( Indy::Source::Invalid, /Unable to open log source/)
168
170
  end
169
171
 
170
172
  end
171
173
 
172
174
  it "using :file" do
173
- require 'tempfile'
174
- file = stub!(:size).and_return(1)
175
- lambda{ Indy.search(:file => file) }
175
+ expect(Indy.search(:file => "#{File.dirname(__FILE__)}/data.log").all.length).to eq(2)
176
176
  end
177
177
 
178
178
  it "using :string" do
179
179
  string = "2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION."
180
180
  string_io = StringIO.new(string)
181
- StringIO.should_receive(:new).with(string).ordered.and_return(string_io)
182
- Indy.search(:string => string).for(:application => 'MyApp').length.should == 1
181
+ expect(StringIO).to receive(:new).with(string).ordered.and_return(string_io)
182
+ expect(Indy.search(:string => string).for(:application => 'MyApp').length).to eq(1)
183
183
  end
184
184
 
185
185
  it "should raise error when given an invalid key" do
186
- lambda{ Indy.search(:foo => "a string").all }.should raise_error( Indy::Source::Invalid )
186
+ expect{ Indy.search(:foo => "a string").all }.to raise_error( Indy::Source::Invalid )
187
187
  end
188
188
 
189
189
  end
@@ -196,7 +196,7 @@ describe 'Indy' do
196
196
  log = [ "2000-09-07 14:06:41 INFO MyApp - Entering APPLICATION.",
197
197
  "2000-09-07 14:07:42 DEBUG MyApp - Initializing APPLICATION.",
198
198
  "2000-09-07 14:07:43 INFO MyApp - Exiting APPLICATION."].join("\n")
199
- Indy.search(log).all.length.should == 3
199
+ expect(Indy.search(log).all.length).to eq(3)
200
200
  end
201
201
 
202
202
  it "should ignore invalid entries" do
@@ -204,13 +204,13 @@ describe 'Indy' do
204
204
  "2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION.\n",
205
205
  " bad \n",
206
206
  "2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION.\n\n"].join("\n")
207
- Indy.search(log).all.length.should == 3
207
+ expect(Indy.search(log).all.length).to eq(3)
208
208
  end
209
209
 
210
210
  it "should handle no matching entries" do
211
211
  log = ["2000-09-07 MyApp - Entering APPLICATION.\n \n",
212
212
  "2000-09-07 14:07:41\n"].join
213
- Indy.search(log).all.length.should == 0
213
+ expect(Indy.search(log).all.length).to eq(0)
214
214
  end
215
215
 
216
216
  context "with explicit time format" do
@@ -223,7 +223,7 @@ describe 'Indy' do
223
223
  :time_format => '%d-%Y-%m',
224
224
  :entry_regexp => /^(\d\d-\d\d\d\d-\d\d)\s+(#{Indy::LogFormats::DEFAULT_SEVERITY_PATTERN})\s+(#{Indy::LogFormats::DEFAULT_APPLICATION})\s+-\s+(#{Indy::LogFormats::DEFAULT_MESSAGE})$/,
225
225
  :entry_fields => Indy::LogFormats::DEFAULT_ENTRY_FIELDS)
226
- indy.all.length.should == 2
226
+ expect(indy.all.length).to eq(2)
227
227
  end
228
228
  end
229
229
 
@@ -242,20 +242,20 @@ describe 'Indy' do
242
242
  end
243
243
 
244
244
  it "should return all entries using #all" do
245
- @indy.all.count.should == 5
245
+ expect(@indy.all.count).to eq(5)
246
246
  end
247
247
 
248
248
  it "should return correct number of entries with #for" do
249
- @indy.for(:severity => 'INFO').count.should == 3
249
+ expect(@indy.for(:severity => 'INFO').count).to eq(3)
250
250
  end
251
251
 
252
252
  it "should return correct number of entries with #like" do
253
- @indy.like(:message => 'ntering').count.should == 2
253
+ expect(@indy.like(:message => 'ntering').count).to eq(2)
254
254
  end
255
255
 
256
256
  it "should return correct number of entries using #after time scope" do
257
257
  results = @indy.after(:time => '2000-09-07 14:07:43', :inclusive => false).all
258
- results.length.should == 2
258
+ expect(results.length).to eq(2)
259
259
  end
260
260
 
261
261
  end
@@ -270,7 +270,7 @@ describe 'Indy' do
270
270
 
271
271
  it "with #for should yield Struct::Entry" do
272
272
  Indy.search(log).all do |result|
273
- result.should be_kind_of(Struct::Entry)
273
+ expect(result).to be_kind_of(Struct::Entry)
274
274
  end
275
275
  end
276
276
 
@@ -279,7 +279,7 @@ describe 'Indy' do
279
279
  Indy.search(log).all do |result|
280
280
  actual_yield_count += 1
281
281
  end
282
- actual_yield_count.should == 3
282
+ expect(actual_yield_count).to eq(3)
283
283
  end
284
284
 
285
285
  it "with #for should yield each entry" do
@@ -287,7 +287,7 @@ describe 'Indy' do
287
287
  Indy.search(log).for(:severity => 'INFO') do |result|
288
288
  actual_yield_count += 1
289
289
  end
290
- actual_yield_count.should == 2
290
+ expect(actual_yield_count).to eq(2)
291
291
  end
292
292
 
293
293
  it "with #like should yield each entry" do
@@ -295,7 +295,7 @@ describe 'Indy' do
295
295
  Indy.search(log).like(:message => '\be\S+ing') do |result|
296
296
  actual_yield_count += 1
297
297
  end
298
- actual_yield_count.should == 2
298
+ expect(actual_yield_count).to eq(2)
299
299
  end
300
300
 
301
301
  end