Test that grammars.yml lists the right scopes for each submodule

convert-grammars now supports a few flags that we can use to make it
dump out the YAML just for the local grammar submodules. We can then
compare this to the YAML that's actually in grammars.yml to check that
they're the same. If they aren't, grammars.yml needs to be updated.
This will help catch mistakes like using the wrong scope name.
This commit is contained in:
Adam Roben
2014-12-22 16:35:01 -05:00
parent 78a0030d46
commit ada6f6882a
2 changed files with 63 additions and 10 deletions

View File

@@ -2,6 +2,7 @@
require 'json'
require 'net/http'
require 'optparse'
require 'plist'
require 'set'
require 'tmpdir'
@@ -13,6 +14,13 @@ GRAMMARS_PATH = File.join(ROOT, "grammars")
SOURCES_FILE = File.join(ROOT, "grammars.yml")
CSONC = File.join(ROOT, "node_modules", ".bin", "csonc")
$options = {
:add => false,
:install => true,
:output => SOURCES_FILE,
:remote => true,
}
class SingleFile
def initialize(path)
@path = path
@@ -148,8 +156,9 @@ def load_grammar(path)
end
end
def install_grammar(tmp_dir, source, all_scopes)
def load_grammars(tmp_dir, source, all_scopes)
is_url = source.start_with?("http:", "https:")
return [] if is_url && !$options[:remote]
is_single_file = source.end_with?('.tmLanguage', '.plist')
p = if !is_url
@@ -172,9 +181,7 @@ def install_grammar(tmp_dir, source, all_scopes)
raise "Unsupported source: #{source}" unless p
installed = []
p.fetch(tmp_dir).each do |path|
p.fetch(tmp_dir).map do |path|
grammar = load_grammar(path)
scope = grammar['scopeName']
@@ -184,9 +191,17 @@ def install_grammar(tmp_dir, source, all_scopes)
" Previous package: #{all_scopes[scope]}"
next
end
File.write(File.join(GRAMMARS_PATH, "#{scope}.json"), JSON.pretty_generate(grammar))
all_scopes[scope] = p.url
grammar
end
end
def install_grammars(grammars)
installed = []
grammars.each do |grammar|
scope = grammar['scopeName']
File.write(File.join(GRAMMARS_PATH, "#{scope}.json"), JSON.pretty_generate(grammar))
installed << scope
end
@@ -206,7 +221,8 @@ def run_thread(queue, all_scopes)
dir = "#{tmpdir}/#{index}"
Dir.mkdir(dir)
install_grammar(dir, source, all_scopes)
grammars = load_grammars(dir, source, all_scopes)
install_grammars(grammars) if $options[:install]
end
end
end
@@ -232,9 +248,9 @@ def main(sources)
all_scopes = {}
if ARGV[0] == '--add'
if $options[:add]
Dir.mktmpdir do |tmpdir|
install_grammar(tmpdir, ARGV[1], all_scopes)
install_grammar(tmpdir, ARGV[0], all_scopes)
end
generate_yaml(all_scopes, sources)
else
@@ -252,12 +268,36 @@ def main(sources)
end
end
OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options]"
opts.on("--add GRAMMAR", "Add a new grammar. GRAMMAR may be a file path or URL.") do |a|
$options[:add] = a
end
opts.on("--[no-]install", "Install grammars into grammars/ directory.") do |i|
$options[:install] = i
end
opts.on("--output FILE", "Write output to FILE. Use - for stdout.") do |o|
$options[:output] = o == "-" ? $stdout : o
end
opts.on("--[no-]remote", "Download remote grammars.") do |r|
$options[:remote] = r
end
end.parse!
sources = File.open(SOURCES_FILE) do |file|
YAML.load(file)
end
yaml = main(sources)
File.write(SOURCES_FILE, YAML.dump(yaml))
if $options[:output].is_a?(IO)
$options[:output].write(YAML.dump(yaml))
else
File.write($options[:output], YAML.dump(yaml))
end
$stderr.puts("Done")

View File

@@ -36,4 +36,17 @@ class TestGrammars < Minitest::Test
assert nonexistent_submodules.empty? && unlisted_submodules.empty?, message
end
def test_local_scopes_are_in_sync
actual = YAML.load(`"#{File.join(ROOT, "script", "convert-grammars")}" --output - --no-install --no-remote 2>/dev/null`)
assert_predicate $?, :success?
# We're not checking remote grammars. That can take a long time and make CI
# flaky if network conditions are poor.
@grammars.delete_if { |k, v| k.start_with?("http:", "https:") }
@grammars.each do |k, v|
assert_equal v, actual[k], "The scopes listed for #{k} in grammars.yml don't match the scopes found in that repository"
end
end
end