recog 2.3.22 → 2.3.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/.github/workflows/verify.yml +1 -1
  4. data/.vscode/bin/monitor-recog-fingerprints.sh +54 -0
  5. data/.vscode/extensions.json +5 -0
  6. data/.vscode/settings.json +8 -0
  7. data/.vscode/tasks.json +77 -0
  8. data/CONTRIBUTING.md +2 -0
  9. data/bin/recog_verify +42 -7
  10. data/cpe-remap.yaml +20 -2
  11. data/features/data/schema_failure.xml +4 -0
  12. data/features/data/tests_with_failures.xml +6 -0
  13. data/features/support/hooks.rb +9 -0
  14. data/features/verify.feature +81 -17
  15. data/identifiers/hw_device.txt +2 -0
  16. data/identifiers/hw_product.txt +2 -0
  17. data/identifiers/os_device.txt +2 -0
  18. data/identifiers/os_family.txt +1 -0
  19. data/identifiers/os_product.txt +8 -1
  20. data/identifiers/service_product.txt +14 -0
  21. data/identifiers/vendor.txt +13 -1
  22. data/lib/recog/fingerprint.rb +21 -7
  23. data/lib/recog/fingerprint_parse_error.rb +10 -0
  24. data/lib/recog/verifier.rb +4 -4
  25. data/lib/recog/verify_reporter.rb +7 -6
  26. data/lib/recog/version.rb +1 -1
  27. data/requirements.txt +1 -1
  28. data/spec/data/external_example_fingerprint/hp_printer_ex_01.txt +1 -0
  29. data/spec/data/external_example_fingerprint/hp_printer_ex_02.txt +1 -0
  30. data/spec/data/external_example_fingerprint.xml +8 -0
  31. data/spec/data/external_example_illegal_path_fingerprint.xml +7 -0
  32. data/spec/lib/recog/db_spec.rb +84 -61
  33. data/spec/lib/recog/fingerprint_spec.rb +4 -4
  34. data/spec/lib/recog/verify_reporter_spec.rb +8 -8
  35. data/update_cpes.py +129 -36
  36. data/xml/apache_os.xml +61 -19
  37. data/xml/architecture.xml +15 -1
  38. data/xml/dhcp_vendor_class.xml +1 -1
  39. data/xml/dns_versionbind.xml +16 -13
  40. data/xml/favicons.xml +87 -5
  41. data/xml/fingerprints.xsd +9 -1
  42. data/xml/ftp_banners.xml +131 -141
  43. data/xml/h323_callresp.xml +2 -2
  44. data/xml/hp_pjl_id.xml +81 -81
  45. data/xml/html_title.xml +178 -9
  46. data/xml/http_cookies.xml +83 -27
  47. data/xml/http_servers.xml +409 -269
  48. data/xml/http_wwwauth.xml +70 -37
  49. data/xml/imap_banners.xml +2 -2
  50. data/xml/nntp_banners.xml +8 -5
  51. data/xml/ntp_banners.xml +33 -33
  52. data/xml/operating_system.xml +92 -77
  53. data/xml/pop_banners.xml +17 -17
  54. data/xml/sip_banners.xml +16 -5
  55. data/xml/sip_user_agents.xml +122 -27
  56. data/xml/smb_native_lm.xml +5 -5
  57. data/xml/smb_native_os.xml +25 -25
  58. data/xml/smtp_banners.xml +132 -131
  59. data/xml/smtp_help.xml +1 -1
  60. data/xml/snmp_sysdescr.xml +1227 -1227
  61. data/xml/snmp_sysobjid.xml +2 -2
  62. data/xml/ssh_banners.xml +9 -5
  63. data/xml/telnet_banners.xml +49 -0
  64. data/xml/tls_jarm.xml +22 -2
  65. data/xml/x11_banners.xml +3 -3
  66. data/xml/x509_issuers.xml +3 -2
  67. data/xml/x509_subjects.xml +3 -3
  68. metadata +19 -3
  69. data/lib/recog/verifier_factory.rb +0 -13
@@ -20,6 +20,7 @@ Active Directory Controller
20
20
  Active Intelligence Engine
21
21
  ActiveMQ
22
22
  AdGuard Home
23
+ Adminer
23
24
  AirTunes
24
25
  Airflow
25
26
  Alteon Web Switch
@@ -30,6 +31,7 @@ Apache Tomcat HTTP Connector
30
31
  AppleShare IP Mail Server
31
32
  Application Load Balancer
32
33
  Application Protection System, Enterprise
34
+ Application Server
33
35
  Application Server Portal
34
36
  Application Server Web Cache
35
37
  Appweb
@@ -50,6 +52,7 @@ BlackJumboDog
50
52
  BladeSystems
51
53
  Boa
52
54
  Bugzilla
55
+ CALDERA
53
56
  CCProxy
54
57
  CMS
55
58
  CMS400.NET
@@ -90,6 +93,7 @@ CouchDB
90
93
  Couchbase Server
91
94
  Courier IMAP
92
95
  Courier POP
96
+ Covenant
93
97
  Cowboy
94
98
  Coyote
95
99
  Cross Web Server
@@ -194,6 +198,7 @@ HttpProxy
194
198
  Hummingbird Exceed X server
195
199
  IBM Domino
196
200
  IIS
201
+ ILOM
197
202
  IMail Server
198
203
  IOS
199
204
  IPVA
@@ -451,7 +456,9 @@ SmartDNS
451
456
  SmartSense Tool
452
457
  SmbFTPD
453
458
  Snowball
459
+ Solr
454
460
  SonarQube
461
+ Spark
455
462
  SpeedTouch
456
463
  Splunk
457
464
  Squeezebox
@@ -473,6 +480,7 @@ TCPIP POP server
473
480
  TUX Web Server
474
481
  Tableau Server
475
482
  TeamCity
483
+ TeamSpeak
476
484
  Tengine
477
485
  TestCenter IQ
478
486
  Thin
@@ -531,6 +539,7 @@ WebGUI
531
539
  WebLogic
532
540
  WebServer
533
541
  WebShield
542
+ WebSocket++
534
543
  WebSphere
535
544
  WebSphere Load Balancer
536
545
  WebTrends
@@ -581,6 +590,7 @@ gSOAP
581
590
  gdnsd
582
591
  httpd
583
592
  iLO
593
+ iPlanet Web Server
584
594
  iScale
585
595
  inetutils ftpd
586
596
  ipGENADevice
@@ -590,6 +600,7 @@ libupnp
590
600
  lighttpd
591
601
  micro_httpd
592
602
  mini_httpd
603
+ mitmproxy
593
604
  mod_access
594
605
  mod_access_compat
595
606
  mod_actions
@@ -737,17 +748,20 @@ mod_vhost_alias
737
748
  mod_watchdog
738
749
  mod_wsgi
739
750
  mod_xml2enc
751
+ mongo-express
740
752
  nginx
741
753
  noVNC
742
754
  ntopng
743
755
  ownCloud Server
744
756
  perl
745
757
  pfSense
758
+ phpMyAdmin
746
759
  qmail
747
760
  qpopper-mysql
748
761
  raptor
749
762
  rbldnsd
750
763
  sfcb
764
+ sofia-sip
751
765
  sshlib
752
766
  thttpd
753
767
  tnftpd
@@ -36,6 +36,7 @@ Accelerated Technology
36
36
  AdGuard
37
37
  Adaptec
38
38
  AdminDroid
39
+ Adminer
39
40
  Adobe
40
41
  Adtran
41
42
  Aerohive
@@ -227,6 +228,7 @@ Eclipse
227
228
  Ektron
228
229
  Elastic
229
230
  Eltek
231
+ Eltex
230
232
  EmbedThis
231
233
  Embedthis
232
234
  Emby
@@ -410,6 +412,7 @@ Lucent
410
412
  Lynx Technology
411
413
  Lyris
412
414
  MBP Kommunikationssysteme GmbH
415
+ MITRE
413
416
  MPI Technologies
414
417
  MPS Software
415
418
  MRV Communications
@@ -478,6 +481,7 @@ NetData
478
481
  NetIQ
479
482
  NetSarang Computer, Inc.
480
483
  NetWin
484
+ Netgate
481
485
  Netgear
482
486
  Netia
483
487
  Netopia
@@ -645,6 +649,7 @@ Segger
645
649
  Sendmail
646
650
  Sequent
647
651
  Sercomm
652
+ SerenityOS
648
653
  Serome Technology, Inc.
649
654
  Serv-U
650
655
  ServerTech
@@ -710,6 +715,7 @@ Tableau
710
715
  Tandberg
711
716
  Taobao
712
717
  Tasman Networks
718
+ TeamSpeak
713
719
  Technicolor
714
720
  Tektronix
715
721
  Teldat H. Kruszynski, M. Cichocki Sp. J.
@@ -732,6 +738,8 @@ Tinyproxy Project
732
738
  Tivo
733
739
  Tobit Software
734
740
  Tokutek
741
+ Tomato
742
+ TomatoUSB
735
743
  Tor Project
736
744
  TornadoWeb
737
745
  Toshiba
@@ -797,7 +805,7 @@ XAMPP
797
805
  XFree86
798
806
  XRoads
799
807
  Xerox
800
- Xiongmai Tech
808
+ Xiongmai Technology
801
809
  Xiph
802
810
  Xiph.org
803
811
  Xitami
@@ -812,6 +820,7 @@ Youngzsoft
812
820
  ZMailer
813
821
  ZTE
814
822
  Zabbix
823
+ Zaphoyd Studios
815
824
  ZebraNet
816
825
  Zed Shaw
817
826
  Zyxel
@@ -833,14 +842,17 @@ iXsystems
833
842
  innovaphone
834
843
  libssh
835
844
  lighttpd
845
+ mitmproxy
836
846
  mod_ssl
837
847
  mod_wsgi
848
+ mongo-express Project
838
849
  nginx
839
850
  ninenines
840
851
  noVNC
841
852
  ntop
842
853
  ownCloud
843
854
  pfSense
855
+ phpMyAdmin
844
856
  port25
845
857
  qmail
846
858
  rPath
@@ -5,6 +5,7 @@ module Recog
5
5
  class Fingerprint
6
6
  require 'set'
7
7
 
8
+ require 'recog/fingerprint_parse_error'
8
9
  require 'recog/fingerprint/regexp_factory'
9
10
  require 'recog/fingerprint/test'
10
11
 
@@ -28,20 +29,27 @@ class Fingerprint
28
29
  # @return (see #parse_examples)
29
30
  attr_reader :tests
30
31
 
32
+ # The line number of the XML entity in the source file for this
33
+ # fingerprint.
34
+ #
35
+ # @return [Integer] The line number of this entity.
36
+ attr_reader :line
37
+
31
38
  # @param xml [Nokogiri::XML::Element]
32
39
  # @param match_key [String] See Recog::DB
33
40
  # @param protocol [String] Protocol such as ftp, mssql, http, etc.
34
- # @param filepath [String] Directory path for fingerprint example files
35
- def initialize(xml, match_key=nil, protocol=nil, filepath=nil)
41
+ # @param example_path [String] Directory path for fingerprint example files
42
+ def initialize(xml, match_key=nil, protocol=nil, example_path=nil)
36
43
  @match_key = match_key
37
44
  @protocol = protocol
38
45
  @name = parse_description(xml)
39
46
  @regex = create_regexp(xml)
47
+ @line = xml.line
40
48
  @params = {}
41
49
  @tests = []
42
50
 
43
51
  @protocol.downcase! if @protocol
44
- parse_examples(xml, filepath)
52
+ parse_examples(xml, example_path)
45
53
  parse_params(xml)
46
54
  end
47
55
 
@@ -161,6 +169,7 @@ class Fingerprint
161
169
  # look for the presence of test cases
162
170
  if tests.size == 0
163
171
  yield :warn, "'#{@name}' has no test cases"
172
+ return
164
173
  end
165
174
 
166
175
  # make sure each test case passes
@@ -226,7 +235,7 @@ class Fingerprint
226
235
  if !param_used
227
236
  message = "'#{@name}' is missing an example that checks for parameter '#{param_name}' " +
228
237
  "which is derived from a capture group"
229
- yield :warn, message
238
+ yield :fail, message
230
239
  end
231
240
  end
232
241
  end
@@ -249,9 +258,9 @@ class Fingerprint
249
258
  end
250
259
 
251
260
  # @param xml [Nokogiri::XML::Element]
252
- # @param filepath [String] Directory path for fingerprint example files
261
+ # @param example_path [String] Directory path for fingerprint example files
253
262
  # @return [void]
254
- def parse_examples(xml, filepath)
263
+ def parse_examples(xml, example_path)
255
264
  elements = xml.xpath('example')
256
265
 
257
266
  elements.each do |elem|
@@ -259,7 +268,12 @@ class Fingerprint
259
268
  attrs = elem.attributes.values.reduce({}) { |a,e| a.merge(e.name => e.value) }
260
269
  if attrs["_filename"]
261
270
  contents = ""
262
- fn = File.join(filepath, attrs["_filename"])
271
+ filename = attrs["_filename"]
272
+ fn = File.expand_path(File.join(example_path, filename))
273
+ unless fn.start_with?(File.expand_path(example_path) + File::Separator)
274
+ raise FingerprintParseError.new("an example specifies an illegal file path '#{filename}'", line_number = @line)
275
+ end
276
+
263
277
  File.open(fn, "rb") do |file|
264
278
  contents = file.read
265
279
  contents.force_encoding(Encoding::ASCII_8BIT)
@@ -0,0 +1,10 @@
1
+ module Recog
2
+ class FingerprintParseError < StandardError
3
+ attr_reader :line_number
4
+
5
+ def initialize(msg, line_number=nil)
6
+ @line_number = line_number
7
+ super(msg)
8
+ end
9
+ end
10
+ end
@@ -15,9 +15,9 @@ class Verifier
15
15
  fp.verify_params do |status, message|
16
16
  case status
17
17
  when :warn
18
- reporter.warning "WARN: #{message}"
18
+ reporter.warning message, fp.line
19
19
  when :fail
20
- reporter.failure "FAIL: #{message}"
20
+ reporter.failure message, fp.line
21
21
  when :success
22
22
  reporter.success(message)
23
23
  end
@@ -25,9 +25,9 @@ class Verifier
25
25
  fp.verify_tests do |status, message|
26
26
  case status
27
27
  when :warn
28
- reporter.warning "WARN: #{message}"
28
+ reporter.warning message, fp.line
29
29
  when :fail
30
- reporter.failure "FAIL: #{message}"
30
+ reporter.failure message, fp.line
31
31
  when :success
32
32
  reporter.success(message)
33
33
  end
@@ -24,15 +24,15 @@ class VerifyReporter
24
24
  formatter.success_message("#{padding}#{text}") if detail?
25
25
  end
26
26
 
27
- def warning(text)
27
+ def warning(text, line=nil)
28
28
  return unless @options.warnings
29
29
  @warning_count += 1
30
- formatter.warning_message("#{path_label}#{padding}#{text}")
30
+ formatter.warning_message("#{path_label(line)}#{padding}WARN: #{text}")
31
31
  end
32
32
 
33
- def failure(text)
33
+ def failure(text, line=nil)
34
34
  @failure_count += 1
35
- formatter.failure_message("#{path_label}#{padding}#{text}")
35
+ formatter.failure_message("#{path_label(line)}#{padding}FAIL: #{text}")
36
36
  end
37
37
 
38
38
  def print_name(fingerprint)
@@ -65,9 +65,10 @@ class VerifyReporter
65
65
  @options.detail
66
66
  end
67
67
 
68
- def path_label
68
+ def path_label(line=nil)
69
69
  unless detail?
70
- @path.to_s.empty? ? "" : "#{@path}: "
70
+ line_label = line ? line.to_s + ":" : ""
71
+ @path.to_s.empty? ? "" : "#{@path}:#{line_label} "
71
72
  end
72
73
  end
73
74
 
data/lib/recog/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Recog
2
- VERSION = '2.3.22'
2
+ VERSION = '2.3.23'
3
3
  end
data/requirements.txt CHANGED
@@ -1,2 +1,2 @@
1
- lxml==4.6.3
1
+ lxml==4.6.5
2
2
  pyyaml
@@ -0,0 +1 @@
1
+ HP LaserJet 4100 Series
@@ -0,0 +1 @@
1
+ HP LaserJet 2200
@@ -0,0 +1,8 @@
1
+ <fingerprints>
2
+ <fingerprint pattern="laserjet (.*)(?: series)?" flags="REG_ICASE">
3
+ <description>HP JetDirect Printer</description>
4
+ <example _filename="hp_printer_ex_01.txt"/>
5
+ <example _filename="hp_printer_ex_02.txt"/>
6
+ <param pos="0" name="service.vendor" value="HP"/>
7
+ </fingerprint>
8
+ </fingerprints>
@@ -0,0 +1,7 @@
1
+ <fingerprints>
2
+ <fingerprint pattern="laserjet (.*)(?: series)?" flags="REG_ICASE">
3
+ <description>HP JetDirect Printer</description>
4
+ <example _filename="../bad_path.txt"/>
5
+ <param pos="0" name="service.vendor" value="HP"/>
6
+ </fingerprint>
7
+ </fingerprints>
@@ -1,97 +1,120 @@
1
1
  require 'recog/db'
2
2
 
3
3
  describe Recog::DB do
4
- let(:xml_file) { File.expand_path File.join('spec', 'data', 'test_fingerprints.xml') }
5
- subject { Recog::DB.new(xml_file) }
6
4
 
7
5
  describe "#fingerprints" do
8
- subject(:fingerprints) { described_class.new(xml_file).fingerprints }
6
+ context "with inline example content" do
7
+ let(:xml_file) { File.expand_path File.join('spec', 'data', 'test_fingerprints.xml') }
8
+ subject { Recog::DB.new(xml_file) }
9
9
 
10
- it { is_expected.to be_a(Enumerable) }
10
+ subject(:fingerprints) { described_class.new(xml_file).fingerprints }
11
11
 
12
- context "with only a pattern" do
13
- subject(:entry) { described_class.new(xml_file).fingerprints[0] }
12
+ it { is_expected.to be_a(Enumerable) }
14
13
 
15
- it "has a blank name with no description" do
16
- expect(entry.name).to be_empty
17
- end
14
+ context "with only a pattern" do
15
+ subject(:entry) { described_class.new(xml_file).fingerprints[0] }
18
16
 
19
- it "has a pattern" do
20
- expect(entry.regex.source).to eq(".*\\(iSeries\\).*")
21
- end
17
+ it "has a blank name with no description" do
18
+ expect(entry.name).to be_empty
19
+ end
22
20
 
23
- it "has no params" do
24
- expect(entry.params).to be_empty
25
- end
21
+ it "has a pattern" do
22
+ expect(entry.regex.source).to eq(".*\\(iSeries\\).*")
23
+ end
24
+
25
+ it "has no params" do
26
+ expect(entry.params).to be_empty
27
+ end
26
28
 
27
- it "has no tests" do
28
- expect(entry.tests).to be_empty
29
+ it "has no tests" do
30
+ expect(entry.tests).to be_empty
31
+ end
29
32
  end
30
- end
31
33
 
32
- context "with params" do
33
- subject(:entry) { described_class.new(xml_file).fingerprints[1] }
34
+ context "with params" do
35
+ subject(:entry) { described_class.new(xml_file).fingerprints[1] }
34
36
 
35
- it "has a name" do
36
- expect(entry.name).to eq('PalmOS')
37
- end
37
+ it "has a name" do
38
+ expect(entry.name).to eq('PalmOS')
39
+ end
38
40
 
39
- it "has a pattern" do
40
- expect(entry.regex.source).to eq(".*\\(PalmOS\\).*")
41
- end
41
+ it "has a pattern" do
42
+ expect(entry.regex.source).to eq(".*\\(PalmOS\\).*")
43
+ end
42
44
 
43
- it "has params" do
44
- expect(entry.params).to eq({"os.vendor"=>[1, "Palm"], "os.device"=>[2, "General"]})
45
- end
45
+ it "has params" do
46
+ expect(entry.params).to eq({"os.vendor"=>[1, "Palm"], "os.device"=>[2, "General"]})
47
+ end
46
48
 
47
- it "has no tests" do
48
- expect(entry.tests).to be_empty
49
+ it "has no tests" do
50
+ expect(entry.tests).to be_empty
51
+ end
49
52
  end
50
- end
51
53
 
52
- context "with pattern flags" do
53
- subject(:entry) { described_class.new(xml_file).fingerprints[2] }
54
+ context "with pattern flags" do
55
+ subject(:entry) { described_class.new(xml_file).fingerprints[2] }
54
56
 
55
- it "has a name and only uses the first value" do
56
- expect(entry.name).to eq('HP Designjet printer')
57
- end
57
+ it "has a name and only uses the first value" do
58
+ expect(entry.name).to eq('HP Designjet printer')
59
+ end
58
60
 
59
- it 'creates a Regexp with expected flags' do
60
- expect(entry.regex).to be_a(Regexp)
61
- expect(entry.regex.options).to eq(Recog::Fingerprint::RegexpFactory::DEFAULT_FLAGS | Regexp::IGNORECASE)
62
- end
61
+ it 'creates a Regexp with expected flags' do
62
+ expect(entry.regex).to be_a(Regexp)
63
+ expect(entry.regex.options).to eq(Recog::Fingerprint::RegexpFactory::DEFAULT_FLAGS | Regexp::IGNORECASE)
64
+ end
63
65
 
64
- it "has a pattern" do
65
- expect(entry.regex).to be_a(Regexp)
66
- expect(entry.regex.source).to eq("(designjet \\S+)")
67
- end
66
+ it "has a pattern" do
67
+ expect(entry.regex).to be_a(Regexp)
68
+ expect(entry.regex.source).to eq("(designjet \\S+)")
69
+ end
70
+
71
+ it "has params" do
72
+ expect(entry.params).to eq({"service.vendor"=>[0, "HP"]})
73
+ end
68
74
 
69
- it "has params" do
70
- expect(entry.params).to eq({"service.vendor"=>[0, "HP"]})
75
+ it "has no tests" do
76
+ expect(entry.tests).to be_empty
77
+ end
71
78
  end
72
79
 
73
- it "has no tests" do
74
- expect(entry.tests).to be_empty
80
+ context "with test" do
81
+ subject(:entry) { described_class.new(xml_file).fingerprints[3] }
82
+
83
+ it "has a name" do
84
+ expect(entry.name).to eq('HP JetDirect Printer')
85
+ end
86
+
87
+ it "has a pattern" do
88
+ expect(entry.regex.source).to eq("laserjet (.*)(?: series)?")
89
+ end
90
+
91
+ it "has params" do
92
+ expect(entry.params).to eq({"service.vendor"=>[0, "HP"]})
93
+ end
94
+
95
+ it "has tests" do
96
+ expect(entry.tests.map(&:content)).to match_array(["HP LaserJet 4100 Series", "HP LaserJet 2200"])
97
+ end
75
98
  end
76
99
  end
77
100
 
78
- context "with test" do
79
- subject(:entry) { described_class.new(xml_file).fingerprints[3] }
101
+ context "with external example content" do
102
+ let(:xml_file) { File.expand_path File.join('spec', 'data', 'external_example_fingerprint.xml') }
103
+ subject { Recog::DB.new(xml_file) }
80
104
 
81
- it "has a name" do
82
- expect(entry.name).to eq('HP JetDirect Printer')
83
- end
105
+ subject(:entry) { described_class.new(xml_file).fingerprints[0] }
84
106
 
85
- it "has a pattern" do
86
- expect(entry.regex.source).to eq("laserjet (.*)(?: series)?")
107
+ it "has tests" do
108
+ expect(entry.tests.map(&:content)).to match_array(["HP LaserJet 4100 Series", "HP LaserJet 2200"])
87
109
  end
110
+ end
88
111
 
89
- it "has params" do
90
- expect(entry.params).to eq({"service.vendor"=>[0, "HP"]})
91
- end
112
+ context "with external example content illegal path" do
113
+ let(:xml_file) { File.expand_path File.join('spec', 'data', 'external_example_illegal_path_fingerprint.xml') }
114
+ subject { Recog::DB.new(xml_file) }
92
115
 
93
- it "has no tests" do
94
- expect(entry.tests.map(&:content)).to match_array(["HP LaserJet 4100 Series", "HP LaserJet 2200"])
116
+ it "raises an illegal file path error" do
117
+ expect { subject }.to raise_error(/an example specifies an illegal file path '.+'/)
95
118
  end
96
119
  end
97
120
  end
@@ -75,7 +75,7 @@ describe Recog::Fingerprint do
75
75
  let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[6]) }
76
76
 
77
77
  it "identifies when a parameter defined by a capture group is not included in one example" do
78
- expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:warn, String])
78
+ expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String])
79
79
  end
80
80
  end
81
81
 
@@ -83,7 +83,7 @@ describe Recog::Fingerprint do
83
83
  let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[7]) }
84
84
 
85
85
  it "identifies when two parameters defined by a capture groups are not included in one example" do
86
- expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:warn, String], [:warn, String])
86
+ expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String], [:fail, String])
87
87
  end
88
88
  end
89
89
 
@@ -92,7 +92,7 @@ describe Recog::Fingerprint do
92
92
  let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[8]) }
93
93
 
94
94
  it "identifies when a parameter defined by a capture group is not included in one example" do
95
- expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:warn, String])
95
+ expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String])
96
96
  end
97
97
  end
98
98
 
@@ -100,7 +100,7 @@ describe Recog::Fingerprint do
100
100
  let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[9]) }
101
101
 
102
102
  it "identifies when two parameters defined by a capture groups are not included in one example" do
103
- expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:warn, String], [:warn, String])
103
+ expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String], [:fail, String])
104
104
  end
105
105
  end
106
106
 
@@ -22,12 +22,12 @@ describe Recog::VerifyReporter do
22
22
 
23
23
  describe "#report" do
24
24
  it "prints warnings" do
25
- expect(formatter).to receive(:warning_message).with('a warning')
25
+ expect(formatter).to receive(:warning_message).with('WARN: a warning')
26
26
  run_report
27
27
  end
28
28
 
29
29
  it "prints failures" do
30
- expect(formatter).to receive(:failure_message).with('a failure')
30
+ expect(formatter).to receive(:failure_message).with('FAIL: a failure')
31
31
  run_report
32
32
  end
33
33
 
@@ -50,12 +50,12 @@ describe Recog::VerifyReporter do
50
50
  end
51
51
 
52
52
  it "prints warnings" do
53
- expect(formatter).to receive(:warning_message).with(' a warning')
53
+ expect(formatter).to receive(:warning_message).with(' WARN: a warning')
54
54
  run_report
55
55
  end
56
56
 
57
57
  it "prints failures" do
58
- expect(formatter).to receive(:failure_message).with(' a failure')
58
+ expect(formatter).to receive(:failure_message).with(' FAIL: a failure')
59
59
  run_report
60
60
  end
61
61
 
@@ -84,12 +84,12 @@ describe Recog::VerifyReporter do
84
84
  subject { Recog::VerifyReporter.new(double(detail: false, quiet: false, warnings: true), formatter, path) }
85
85
 
86
86
  it "prints warnings" do
87
- expect(formatter).to receive(:warning_message).with("#{path}: a warning")
87
+ expect(formatter).to receive(:warning_message).with("#{path}: WARN: a warning")
88
88
  run_report
89
89
  end
90
90
 
91
91
  it "prints failures" do
92
- expect(formatter).to receive(:failure_message).with("#{path}: a failure")
92
+ expect(formatter).to receive(:failure_message).with("#{path}: FAIL: a failure")
93
93
  run_report
94
94
  end
95
95
 
@@ -118,12 +118,12 @@ describe Recog::VerifyReporter do
118
118
  end
119
119
 
120
120
  it "prints warnings" do
121
- expect(formatter).to receive(:warning_message).with(' a warning')
121
+ expect(formatter).to receive(:warning_message).with(' WARN: a warning')
122
122
  run_report
123
123
  end
124
124
 
125
125
  it "prints failures" do
126
- expect(formatter).to receive(:failure_message).with(' a failure')
126
+ expect(formatter).to receive(:failure_message).with(' FAIL: a failure')
127
127
  run_report
128
128
  end
129
129