csvlint 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +4 -0
  3. data/.github/workflows/push.yml +14 -2
  4. data/.ruby-version +1 -1
  5. data/.standard_todo.yml +43 -0
  6. data/Dockerfile +16 -0
  7. data/Gemfile +2 -2
  8. data/README.md +9 -9
  9. data/Rakefile +7 -7
  10. data/csvlint.gemspec +14 -16
  11. data/docker_notes_for_windows.txt +20 -0
  12. data/features/step_definitions/cli_steps.rb +11 -11
  13. data/features/step_definitions/information_steps.rb +4 -4
  14. data/features/step_definitions/parse_csv_steps.rb +11 -11
  15. data/features/step_definitions/schema_validation_steps.rb +10 -10
  16. data/features/step_definitions/sources_steps.rb +1 -1
  17. data/features/step_definitions/validation_errors_steps.rb +19 -19
  18. data/features/step_definitions/validation_info_steps.rb +9 -9
  19. data/features/step_definitions/validation_warnings_steps.rb +11 -11
  20. data/features/support/aruba.rb +6 -6
  21. data/features/support/earl_formatter.rb +39 -39
  22. data/features/support/env.rb +10 -11
  23. data/features/support/load_tests.rb +107 -103
  24. data/features/support/webmock.rb +2 -2
  25. data/lib/csvlint/cli.rb +133 -130
  26. data/lib/csvlint/csvw/column.rb +279 -280
  27. data/lib/csvlint/csvw/date_format.rb +90 -92
  28. data/lib/csvlint/csvw/metadata_error.rb +1 -3
  29. data/lib/csvlint/csvw/number_format.rb +40 -32
  30. data/lib/csvlint/csvw/property_checker.rb +714 -717
  31. data/lib/csvlint/csvw/table.rb +49 -52
  32. data/lib/csvlint/csvw/table_group.rb +24 -23
  33. data/lib/csvlint/error_collector.rb +2 -0
  34. data/lib/csvlint/error_message.rb +0 -1
  35. data/lib/csvlint/field.rb +153 -141
  36. data/lib/csvlint/schema.rb +34 -42
  37. data/lib/csvlint/validate.rb +161 -143
  38. data/lib/csvlint/version.rb +1 -1
  39. data/lib/csvlint.rb +22 -23
  40. data/spec/csvw/column_spec.rb +15 -16
  41. data/spec/csvw/date_format_spec.rb +5 -7
  42. data/spec/csvw/number_format_spec.rb +2 -4
  43. data/spec/csvw/table_group_spec.rb +103 -105
  44. data/spec/csvw/table_spec.rb +71 -73
  45. data/spec/field_spec.rb +116 -121
  46. data/spec/schema_spec.rb +129 -139
  47. data/spec/spec_helper.rb +6 -6
  48. data/spec/validator_spec.rb +167 -190
  49. metadata +22 -55
@@ -1,12 +1,12 @@
1
- require 'aruba'
2
- require 'aruba/cucumber'
1
+ require "aruba"
2
+ require "aruba/cucumber"
3
3
 
4
- require 'csvlint/cli'
4
+ require "csvlint/cli"
5
5
 
6
6
  module Csvlint
7
7
  class CliRunner
8
8
  # Allow everything fun to be injected from the outside while defaulting to normal implementations.
9
- def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
9
+ def initialize(argv, stdin = $stdin, stdout = $stdout, stderr = $stderr, kernel = Kernel)
10
10
  @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
11
11
  end
12
12
 
@@ -22,11 +22,11 @@ module Csvlint
22
22
 
23
23
  # Thor::Base#start does not have a return value, assume success if no exception is raised.
24
24
  0
25
- rescue StandardError => e
25
+ rescue => e
26
26
  # The ruby interpreter would pipe this to STDERR and exit 1 in the case of an unhandled exception
27
27
  b = e.backtrace
28
28
  @stderr.puts("#{b.shift}: #{e.message} (#{e.class})")
29
- @stderr.puts(b.map{|s| "\tfrom #{s}"}.join("\n"))
29
+ @stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n"))
30
30
  1
31
31
  rescue SystemExit => e
32
32
  e.status
@@ -1,33 +1,33 @@
1
- require 'rdf'
2
- require 'rdf/turtle'
1
+ require "rdf"
2
+ require "rdf/turtle"
3
3
 
4
4
  class EarlFormatter
5
5
  def initialize(step_mother, io, options)
6
6
  output = RDF::Resource.new("")
7
7
  @graph = RDF::Graph.new
8
- @graph << [ CSVLINT, RDF.type, RDF::DOAP.Project ]
9
- @graph << [ CSVLINT, RDF.type, EARL.TestSubject ]
10
- @graph << [ CSVLINT, RDF.type, EARL.Software ]
11
- @graph << [ CSVLINT, RDF::DOAP.name, "csvlint" ]
12
- @graph << [ CSVLINT, RDF::DC.title, "csvlint" ]
13
- @graph << [ CSVLINT, RDF::DOAP.description, "CSV validator" ]
14
- @graph << [ CSVLINT, RDF::DOAP.homepage, RDF::Resource.new("https://github.com/theodi/csvlint.rb") ]
15
- @graph << [ CSVLINT, RDF::DOAP.license, RDF::Resource.new("https://raw.githubusercontent.com/theodi/csvlint.rb/master/LICENSE.md") ]
16
- @graph << [ CSVLINT, RDF::DOAP["programming-language"], "Ruby" ]
17
- @graph << [ CSVLINT, RDF::DOAP.implements, RDF::Resource.new("http://www.w3.org/TR/tabular-data-model/") ]
18
- @graph << [ CSVLINT, RDF::DOAP.implements, RDF::Resource.new("http://www.w3.org/TR/tabular-metadata/") ]
19
- @graph << [ CSVLINT, RDF::DOAP.developer, ODI ]
20
- @graph << [ CSVLINT, RDF::DOAP.maintainer, ODI ]
21
- @graph << [ CSVLINT, RDF::DOAP.documenter, ODI ]
22
- @graph << [ CSVLINT, RDF::FOAF.maker, ODI ]
23
- @graph << [ CSVLINT, RDF::DC.creator, ODI ]
24
- @graph << [ output, RDF::FOAF["primaryTopic"], CSVLINT ]
25
- @graph << [ output, RDF::DC.issued, DateTime.now ]
26
- @graph << [ output, RDF::FOAF.maker, ODI ]
27
- @graph << [ ODI, RDF.type, RDF::FOAF.Organization ]
28
- @graph << [ ODI, RDF.type, EARL.Assertor ]
29
- @graph << [ ODI, RDF::FOAF.name, "Open Data Institute" ]
30
- @graph << [ ODI, RDF::FOAF.homepage, "https://theodi.org/" ]
8
+ @graph << [CSVLINT, RDF.type, RDF::DOAP.Project]
9
+ @graph << [CSVLINT, RDF.type, EARL.TestSubject]
10
+ @graph << [CSVLINT, RDF.type, EARL.Software]
11
+ @graph << [CSVLINT, RDF::DOAP.name, "csvlint"]
12
+ @graph << [CSVLINT, RDF::DC.title, "csvlint"]
13
+ @graph << [CSVLINT, RDF::DOAP.description, "CSV validator"]
14
+ @graph << [CSVLINT, RDF::DOAP.homepage, RDF::Resource.new("https://github.com/theodi/csvlint.rb")]
15
+ @graph << [CSVLINT, RDF::DOAP.license, RDF::Resource.new("https://raw.githubusercontent.com/theodi/csvlint.rb/master/LICENSE.md")]
16
+ @graph << [CSVLINT, RDF::DOAP["programming-language"], "Ruby"]
17
+ @graph << [CSVLINT, RDF::DOAP.implements, RDF::Resource.new("http://www.w3.org/TR/tabular-data-model/")]
18
+ @graph << [CSVLINT, RDF::DOAP.implements, RDF::Resource.new("http://www.w3.org/TR/tabular-metadata/")]
19
+ @graph << [CSVLINT, RDF::DOAP.developer, ODI]
20
+ @graph << [CSVLINT, RDF::DOAP.maintainer, ODI]
21
+ @graph << [CSVLINT, RDF::DOAP.documenter, ODI]
22
+ @graph << [CSVLINT, RDF::FOAF.maker, ODI]
23
+ @graph << [CSVLINT, RDF::DC.creator, ODI]
24
+ @graph << [output, RDF::FOAF["primaryTopic"], CSVLINT]
25
+ @graph << [output, RDF::DC.issued, DateTime.now]
26
+ @graph << [output, RDF::FOAF.maker, ODI]
27
+ @graph << [ODI, RDF.type, RDF::FOAF.Organization]
28
+ @graph << [ODI, RDF.type, EARL.Assertor]
29
+ @graph << [ODI, RDF::FOAF.name, "Open Data Institute"]
30
+ @graph << [ODI, RDF::FOAF.homepage, "https://theodi.org/"]
31
31
  end
32
32
 
33
33
  def scenario_name(keyword, name, file_colon_line, source_indent)
@@ -40,27 +40,27 @@ class EarlFormatter
40
40
  passed = false unless s.status == :passed
41
41
  end
42
42
  a = RDF::Node.new
43
- @graph << [ a, RDF.type, EARL.Assertion ]
44
- @graph << [ a, EARL.assertedBy, ODI ]
45
- @graph << [ a, EARL.subject, CSVLINT ]
46
- @graph << [ a, EARL.test, @test ]
47
- @graph << [ a, EARL.mode, EARL.automatic ]
43
+ @graph << [a, RDF.type, EARL.Assertion]
44
+ @graph << [a, EARL.assertedBy, ODI]
45
+ @graph << [a, EARL.subject, CSVLINT]
46
+ @graph << [a, EARL.test, @test]
47
+ @graph << [a, EARL.mode, EARL.automatic]
48
48
  r = RDF::Node.new
49
- @graph << [ a, EARL.result, r ]
50
- @graph << [ r, RDF.type, EARL.TestResult ]
51
- @graph << [ r, EARL.outcome, passed ? EARL.passed : EARL.failed ]
52
- @graph << [ r, RDF::DC.date, DateTime.now ]
49
+ @graph << [a, EARL.result, r]
50
+ @graph << [r, RDF.type, EARL.TestResult]
51
+ @graph << [r, EARL.outcome, passed ? EARL.passed : EARL.failed]
52
+ @graph << [r, RDF::DC.date, DateTime.now]
53
53
  end
54
54
 
55
55
  def after_features(features)
56
- RDF::Writer.for(:ttl).open("csvlint-earl.ttl", { :prefixes => { "earl" => EARL }, :standard_prefixes => true, :canonicalize => true, :literal_shorthand => true }) do |writer|
56
+ RDF::Writer.for(:ttl).open("csvlint-earl.ttl", {prefixes: {"earl" => EARL}, standard_prefixes: true, canonicalize: true, literal_shorthand: true}) do |writer|
57
57
  writer << @graph
58
- end
58
+ end
59
59
  end
60
60
 
61
61
  private
62
- EARL = RDF::Vocabulary.new("http://www.w3.org/ns/earl#")
63
- ODI = RDF::Resource.new("https://theodi.org/")
64
- CSVLINT = RDF::Resource.new("https://github.com/theodi/csvlint.rb")
65
62
 
63
+ EARL = RDF::Vocabulary.new("http://www.w3.org/ns/earl#")
64
+ ODI = RDF::Resource.new("https://theodi.org/")
65
+ CSVLINT = RDF::Resource.new("https://github.com/theodi/csvlint.rb")
66
66
  end
@@ -1,23 +1,22 @@
1
- require 'coveralls'
2
- Coveralls.wear_merged!('test_frameworks')
1
+ require "coveralls"
2
+ Coveralls.wear_merged!("test_frameworks")
3
3
 
4
- $:.unshift File.join( File.dirname(__FILE__), "..", "..", "lib")
4
+ $:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib")
5
5
 
6
- require 'rspec/expectations'
7
- require 'cucumber/rspec/doubles'
8
- require 'csvlint'
9
- require 'byebug'
6
+ require "rspec/expectations"
7
+ require "cucumber/rspec/doubles"
8
+ require "csvlint"
9
+ require "byebug"
10
10
 
11
- require 'spork'
11
+ require "spork"
12
12
 
13
13
  Spork.each_run do
14
- require 'csvlint'
14
+ require "csvlint"
15
15
  end
16
16
 
17
17
  class CustomWorld
18
18
  def default_csv_options
19
- return {
20
- }
19
+ {}
21
20
  end
22
21
  end
23
22
 
@@ -1,6 +1,6 @@
1
- require 'json'
2
- require 'open-uri'
3
- require 'uri'
1
+ require "json"
2
+ require "open-uri"
3
+ require "uri"
4
4
 
5
5
  BASE_URI = "https://w3c.github.io/csvw/tests/"
6
6
  BASE_PATH = File.join(File.dirname(__FILE__), "..", "fixtures", "csvw")
@@ -11,109 +11,113 @@ SCRIPT_FILE_PATH = File.join(File.dirname(__FILE__), "..", "..", "bin", "run-csv
11
11
  Dir.mkdir(BASE_PATH) unless Dir.exist?(BASE_PATH)
12
12
 
13
13
  def cache_file(filename)
14
- file = File.join(BASE_PATH, filename)
15
- uri = URI.join(BASE_URI, filename)
16
- unless File.exist?(file)
17
- if filename.include? "/"
18
- levels = filename.split("/")[0..-2]
19
- for i in 0..levels.length
20
- dir = File.join(BASE_PATH, levels[0..i].join("/"))
21
- Dir.mkdir(dir) unless Dir.exist?(dir)
22
- end
23
- end
24
- STDERR.puts("storing #{file} locally")
25
- File.open(file, 'wb') do |f|
26
- f.puts URI.open(uri, 'rb').read
27
- end
28
- end
29
- return uri, file
14
+ file = File.join(BASE_PATH, filename)
15
+ uri = URI.join(BASE_URI, filename)
16
+ unless File.exist?(file)
17
+ if filename.include? "/"
18
+ levels = filename.split("/")[0..-2]
19
+ for i in 0..levels.length
20
+ dir = File.join(BASE_PATH, levels[0..i].join("/"))
21
+ Dir.mkdir(dir) unless Dir.exist?(dir)
22
+ end
23
+ end
24
+ warn("storing #{file} locally")
25
+ File.open(file, "wb") do |f|
26
+ f.puts URI.open(uri, "rb").read
27
+ end
28
+ end
29
+ [uri, file]
30
30
  end
31
31
 
32
- File.open(SCRIPT_FILE_PATH, 'w') do |file|
33
- File.chmod(0755, SCRIPT_FILE_PATH)
34
- manifest = JSON.parse( URI.open("#{BASE_URI}manifest-validation.jsonld").read )
35
- manifest["entries"].each do |entry|
36
- type = "valid"
37
- case entry["type"]
38
- when "csvt:WarningValidationTest"
39
- type = "warnings"
40
- when "csvt:NegativeValidationTest"
41
- type = "errors"
42
- end
43
- file.puts "echo \"#{entry["id"].split("#")[-1]}: #{entry["name"].gsub("`", "'")}\""
44
- file.puts "echo \"#{type}: #{entry["comment"].gsub("\"", "\\\"").gsub("`", "'")}\""
45
- if entry["action"].end_with?(".json")
46
- file.puts "csvlint --schema=features/fixtures/csvw/#{entry["action"]}"
47
- elsif entry["option"] && entry["option"]["metadata"]
48
- file.puts "csvlint features/fixtures/csvw/#{entry["action"]} --schema=features/fixtures/csvw/#{entry["option"]["metadata"]}"
49
- else
50
- file.puts "csvlint features/fixtures/csvw/#{entry["action"]}"
51
- end
52
- file.puts "echo"
53
- end
54
- end unless File.exist? SCRIPT_FILE_PATH
32
+ unless File.exist? SCRIPT_FILE_PATH
33
+ File.open(SCRIPT_FILE_PATH, "w") do |file|
34
+ File.chmod(0o755, SCRIPT_FILE_PATH)
35
+ manifest = JSON.parse(URI.open("#{BASE_URI}manifest-validation.jsonld").read)
36
+ manifest["entries"].each do |entry|
37
+ type = "valid"
38
+ case entry["type"]
39
+ when "csvt:WarningValidationTest"
40
+ type = "warnings"
41
+ when "csvt:NegativeValidationTest"
42
+ type = "errors"
43
+ end
44
+ file.puts "echo \"#{entry["id"].split("#")[-1]}: #{entry["name"].tr("`", "'")}\""
45
+ file.puts "echo \"#{type}: #{entry["comment"].gsub("\"", "\\\"").tr("`", "'")}\""
46
+ if entry["action"].end_with?(".json")
47
+ file.puts "csvlint --schema=features/fixtures/csvw/#{entry["action"]}"
48
+ elsif entry["option"] && entry["option"]["metadata"]
49
+ file.puts "csvlint features/fixtures/csvw/#{entry["action"]} --schema=features/fixtures/csvw/#{entry["option"]["metadata"]}"
50
+ else
51
+ file.puts "csvlint features/fixtures/csvw/#{entry["action"]}"
52
+ end
53
+ file.puts "echo"
54
+ end
55
+ end
56
+ end
55
57
 
56
- File.open(VALIDATION_FEATURE_FILE_PATH, 'w') do |file|
57
- file.puts "# Auto-generated file based on standard validation CSVW tests from #{BASE_URI}manifest-validation.jsonld"
58
- file.puts ""
58
+ unless File.exist? VALIDATION_FEATURE_FILE_PATH
59
+ File.open(VALIDATION_FEATURE_FILE_PATH, "w") do |file|
60
+ file.puts "# Auto-generated file based on standard validation CSVW tests from #{BASE_URI}manifest-validation.jsonld"
61
+ file.puts ""
59
62
 
60
- manifest = JSON.parse( URI.open("#{BASE_URI}manifest-validation.jsonld").read )
63
+ manifest = JSON.parse(URI.open("#{BASE_URI}manifest-validation.jsonld").read)
61
64
 
62
- file.puts "Feature: #{manifest["label"]}"
63
- file.puts ""
65
+ file.puts "Feature: #{manifest["label"]}"
66
+ file.puts ""
64
67
 
65
- manifest["entries"].each do |entry|
66
- action_uri, action_file = cache_file(entry["action"])
67
- metadata = nil
68
- provided_files = []
69
- missing_files = []
70
- file.puts "\t# #{entry["id"]}"
71
- file.puts "\t# #{entry["comment"]}"
72
- file.puts "\tScenario: #{entry["id"]} #{entry["name"].gsub("<", "less than")}"
73
- if entry["action"].end_with?(".json")
74
- file.puts "\t\tGiven I have a metadata file called \"csvw/#{entry["action"]}\""
75
- file.puts "\t\tAnd the metadata is stored at the url \"#{action_uri}\""
76
- else
77
- file.puts "\t\tGiven I have a CSV file called \"csvw/#{entry["action"]}\""
78
- file.puts "\t\tAnd it has a Link header holding \"#{entry["httpLink"]}\"" if entry["httpLink"]
79
- file.puts "\t\tAnd it is stored at the url \"#{action_uri}\""
80
- if entry["option"] && entry["option"]["metadata"]
81
- # no need to store the file here, as it will be listed in the 'implicit' list, which all get stored
82
- metadata = URI.join(BASE_URI, entry["option"]["metadata"])
83
- file.puts "\t\tAnd I have a metadata file called \"csvw/#{entry["option"]["metadata"]}\""
84
- file.puts "\t\tAnd the metadata is stored at the url \"#{metadata}\""
85
- end
86
- provided_files << action_uri.to_s
87
- if entry["name"].include?("/.well-known/csvm")
88
- file.puts "\t\tAnd I have a file called \"w3.org/.well-known/csvm\" at the url \"https://www.w3.org/.well-known/csvm\""
89
- missing_files << "#{action_uri}.json"
90
- missing_files << URI.join(action_uri, 'csvm.json').to_s
91
- else
92
- missing_files << URI.join(action_uri, '/.well-known/csvm').to_s
93
- end
94
- missing_files << "#{action_uri}-metadata.json"
95
- missing_files << URI.join(action_uri, 'csv-metadata.json').to_s
96
- end
97
- entry["implicit"].each do |implicit|
98
- implicit_uri, implicit_file = cache_file(implicit)
99
- provided_files << implicit_uri.to_s
100
- unless implicit_uri == metadata
101
- file.puts "\t\tAnd I have a file called \"csvw/#{implicit}\" at the url \"#{implicit_uri}\""
102
- end
103
- end if entry["implicit"]
104
- missing_files.each do |uri|
105
- file.puts "\t\tAnd there is no file at the url \"#{uri}\"" unless provided_files.include? uri
106
- end
107
- file.puts "\t\tWhen I carry out CSVW validation"
108
- if entry["type"] == "csvt:WarningValidationTest"
109
- file.puts "\t\tThen there should not be errors"
110
- file.puts "\t\tAnd there should be warnings"
111
- elsif entry["type"] == "csvt:NegativeValidationTest"
112
- file.puts "\t\tThen there should be errors"
113
- else
114
- file.puts "\t\tThen there should not be errors"
115
- file.puts "\t\tAnd there should not be warnings"
116
- end
117
- file.puts "\t"
118
- end
119
- end unless File.exist? VALIDATION_FEATURE_FILE_PATH
68
+ manifest["entries"].each do |entry|
69
+ action_uri, action_file = cache_file(entry["action"])
70
+ metadata = nil
71
+ provided_files = []
72
+ missing_files = []
73
+ file.puts "\t# #{entry["id"]}"
74
+ file.puts "\t# #{entry["comment"]}"
75
+ file.puts "\tScenario: #{entry["id"]} #{entry["name"].gsub("<", "less than")}"
76
+ if entry["action"].end_with?(".json")
77
+ file.puts "\t\tGiven I have a metadata file called \"csvw/#{entry["action"]}\""
78
+ file.puts "\t\tAnd the metadata is stored at the url \"#{action_uri}\""
79
+ else
80
+ file.puts "\t\tGiven I have a CSV file called \"csvw/#{entry["action"]}\""
81
+ file.puts "\t\tAnd it has a Link header holding \"#{entry["httpLink"]}\"" if entry["httpLink"]
82
+ file.puts "\t\tAnd it is stored at the url \"#{action_uri}\""
83
+ if entry["option"] && entry["option"]["metadata"]
84
+ # no need to store the file here, as it will be listed in the 'implicit' list, which all get stored
85
+ metadata = URI.join(BASE_URI, entry["option"]["metadata"])
86
+ file.puts "\t\tAnd I have a metadata file called \"csvw/#{entry["option"]["metadata"]}\""
87
+ file.puts "\t\tAnd the metadata is stored at the url \"#{metadata}\""
88
+ end
89
+ provided_files << action_uri.to_s
90
+ if entry["name"].include?("/.well-known/csvm")
91
+ file.puts "\t\tAnd I have a file called \"w3.org/.well-known/csvm\" at the url \"https://www.w3.org/.well-known/csvm\""
92
+ missing_files << "#{action_uri}.json"
93
+ missing_files << URI.join(action_uri, "csvm.json").to_s
94
+ else
95
+ missing_files << URI.join(action_uri, "/.well-known/csvm").to_s
96
+ end
97
+ missing_files << "#{action_uri}-metadata.json"
98
+ missing_files << URI.join(action_uri, "csv-metadata.json").to_s
99
+ end
100
+ entry["implicit"]&.each do |implicit|
101
+ implicit_uri, implicit_file = cache_file(implicit)
102
+ provided_files << implicit_uri.to_s
103
+ unless implicit_uri == metadata
104
+ file.puts "\t\tAnd I have a file called \"csvw/#{implicit}\" at the url \"#{implicit_uri}\""
105
+ end
106
+ end
107
+ missing_files.each do |uri|
108
+ file.puts "\t\tAnd there is no file at the url \"#{uri}\"" unless provided_files.include? uri
109
+ end
110
+ file.puts "\t\tWhen I carry out CSVW validation"
111
+ if entry["type"] == "csvt:WarningValidationTest"
112
+ file.puts "\t\tThen there should not be errors"
113
+ file.puts "\t\tAnd there should be warnings"
114
+ elsif entry["type"] == "csvt:NegativeValidationTest"
115
+ file.puts "\t\tThen there should be errors"
116
+ else
117
+ file.puts "\t\tThen there should not be errors"
118
+ file.puts "\t\tAnd there should not be warnings"
119
+ end
120
+ file.puts "\t"
121
+ end
122
+ end
123
+ end
@@ -1,3 +1,3 @@
1
- require 'webmock/cucumber'
1
+ require "webmock/cucumber"
2
2
 
3
- WebMock.disable_net_connect!(allow: %r{csvw/tests})
3
+ WebMock.disable_net_connect!(allow: %r{csvw/tests})