starscope 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- class StarScope::Matcher
1
+ class Starscope::Matcher
2
2
 
3
3
  MATCH_TYPES = [:full_match, :simple_match, :simple_regexp, :full_regexp]
4
4
 
@@ -1,10 +1,11 @@
1
1
  require 'ruby-progressbar'
2
2
 
3
- class StarScope::Output
3
+ class Starscope::Output
4
4
 
5
5
  PBAR_FORMAT = '%t: %c/%C %E ||%b>%i||'
6
6
 
7
- def initialize(level)
7
+ def initialize(level, out=STDOUT)
8
+ @out = out
8
9
  @level = level
9
10
  @pbar = nil
10
11
  end
@@ -12,7 +13,8 @@ class StarScope::Output
12
13
  def new_pbar(title, num_items)
13
14
  if @level != :quiet
14
15
  @pbar = ProgressBar.create(:title => title, :total => num_items,
15
- :format => PBAR_FORMAT, :length => 80)
16
+ :format => PBAR_FORMAT, :length => 80,
17
+ :out => @out)
16
18
  end
17
19
  end
18
20
 
@@ -25,12 +27,12 @@ class StarScope::Output
25
27
  @pbar = nil
26
28
  end
27
29
 
28
- def log(msg)
29
- return if @level != :verbose
30
+ def extra(msg)
31
+ return unless @level == :verbose
30
32
  output(msg)
31
33
  end
32
34
 
33
- def print(msg)
35
+ def normal(msg)
34
36
  return if @level == :quiet
35
37
  output(msg)
36
38
  end
@@ -41,7 +43,7 @@ class StarScope::Output
41
43
  if @pbar
42
44
  @pbar.log(msg)
43
45
  else
44
- puts msg
46
+ @out.puts msg
45
47
  end
46
48
  end
47
49
 
@@ -1,3 +1,3 @@
1
- module StarScope
2
- VERSION = "1.1.2"
1
+ module Starscope
2
+ VERSION = "1.2.0"
3
3
  end
data/starscope.gemspec CHANGED
@@ -2,7 +2,7 @@ require File.expand_path('../lib/starscope/version.rb', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = 'starscope'
5
- gem.version = StarScope::VERSION
5
+ gem.version = Starscope::VERSION
6
6
  gem.summary = "A code indexer and analyzer"
7
7
  gem.description = "A tool like the venerable cscope, but for ruby, golang and other languages"
8
8
  gem.authors = ["Evan Huus"]
@@ -22,4 +22,5 @@ Gem::Specification.new do |gem|
22
22
  gem.add_development_dependency 'rake'
23
23
  gem.add_development_dependency 'pry'
24
24
  gem.add_development_dependency 'minitest'
25
+ gem.add_development_dependency 'mocha'
25
26
  end
@@ -0,0 +1,8 @@
1
+ 5
2
+ {
3
+ ":paths": ["test/fixtures/**/*"],
4
+ ":excludes": [],
5
+ ":langs": {},
6
+ ":files": {}
7
+ }
8
+ {}
@@ -0,0 +1,15 @@
1
+ 5
2
+ {
3
+ ":paths": [],
4
+ ":excludes": [],
5
+ ":langs": {
6
+ ":Go": 0
7
+ },
8
+ ":files": {
9
+ "test/fixtures/sample_golang.go": {
10
+ ":last_updated": 10000000000,
11
+ ":lang": ":Go"
12
+ }
13
+ }
14
+ }
15
+ {}
@@ -0,0 +1,15 @@
1
+ 5
2
+ {
3
+ ":paths": [],
4
+ ":excludes": [],
5
+ ":langs": {
6
+ ":Go": 1234
7
+ },
8
+ ":files": {
9
+ "test/fixtures/sample_golang.go": {
10
+ ":last_updated": 1,
11
+ ":lang": ":Go"
12
+ }
13
+ }
14
+ }
15
+ {}
@@ -0,0 +1,12 @@
1
+ 5
2
+ {
3
+ ":paths": ["test/fixtures/**/*"],
4
+ ":excludes": [],
5
+ ":langs": {},
6
+ ":files": {
7
+ "test/fixtures/foo": {
8
+ ":last_updated": 1
9
+ }
10
+ }
11
+ }
12
+ {}
@@ -0,0 +1,15 @@
1
+ 5
2
+ {
3
+ ":paths": [],
4
+ ":excludes": [],
5
+ ":langs": {
6
+ ":Go": 1234
7
+ },
8
+ ":files": {
9
+ "test/fixtures/sample_golang.go": {
10
+ ":last_updated": 10000000000,
11
+ ":lang": ":Go"
12
+ }
13
+ }
14
+ }
15
+ {}
@@ -2,11 +2,11 @@ require 'date'
2
2
  require 'zlib'
3
3
 
4
4
  LANGS = [
5
- StarScope::Lang::Go,
6
- StarScope::Lang::Ruby
5
+ Starscope::Lang::Go,
6
+ Starscope::Lang::Ruby
7
7
  ]
8
8
 
9
- class StarScope::DB
9
+ class Starscope::DB
10
10
 
11
11
  PBAR_FORMAT = '%t: %c/%C %E ||%b>%i||'
12
12
 
@@ -20,21 +20,21 @@ class StarScope::DB
20
20
  self.foo = :bar
21
21
  end
22
22
 
23
- def load(file)
24
- File.open(file, 'r') do |file|
25
- Zlib::GzipReader.wrap(file) do |file|
26
- format = file.gets.to_i
23
+ def load(filename)
24
+ File.open(filename, 'r') do |file|
25
+ Zlib::GzipReader.wrap(file) do |stream|
26
+ format = stream.gets.to_i
27
27
  if format == DB_FORMAT
28
- @paths = Oj.load(file.gets)
29
- @files = Oj.load(file.gets)
30
- @tables = Oj.load(file.gets, :symbol_keys => true)
28
+ @paths = Oj.load(stream.gets)
29
+ @files = Oj.load(stream.gets)
30
+ @tables = Oj.load(stream.gets, :symbol_keys => true)
31
31
  elsif format <= 2
32
32
  # Old format (pre-json), so read the directories segment then rebuild
33
- len = file.gets.to_i
34
- add_paths(Marshal::load(file.read(len)))
33
+ len = stream.gets.to_i
34
+ add_paths(Marshal::load(stream.read(len)))
35
35
  elsif format < DB_FORMAT
36
36
  # Old format, so read the directories segment then rebuild
37
- add_paths(Oj.load(file.gets))
37
+ add_paths(Oj.load(stream.gets))
38
38
  elsif format > DB_FORMAT
39
39
  raise UnknownDBFormatError
40
40
  end
@@ -42,13 +42,13 @@ class StarScope::DB
42
42
  end
43
43
  end
44
44
 
45
- def save(file)
46
- File.open(file, 'w') do |file|
47
- Zlib::GzipWriter.wrap(file) do |file|
48
- file.puts DB_FORMAT
49
- file.puts Oj.dump @paths
50
- file.puts Oj.dump @files
51
- file.puts Oj.dump @tables
45
+ def save(filename)
46
+ File.open(filename, 'w') do |file|
47
+ Zlib::GzipWriter.wrap(file) do |stream|
48
+ stream.puts DB_FORMAT
49
+ stream.puts Oj.dump @paths
50
+ stream.puts Oj.dump @files
51
+ stream.puts Oj.dump @tables
52
52
  end
53
53
  end
54
54
  end
@@ -134,7 +134,7 @@ class StarScope::DB
134
134
  key = key.to_sym
135
135
  @tables[tbl] ||= {}
136
136
  @tables[tbl][key] ||= []
137
- @tables[tbl][key] << StarScope::Datum.build(file, key, args)
137
+ @tables[tbl][key] << Starscope::Datum.build(file, key, args)
138
138
  end
139
139
  end
140
140
  end
@@ -0,0 +1,57 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ describe "starscope executable script" do
4
+
5
+ BASE = "bundle exec bin/starscope --quiet"
6
+ EXTRACT = "#{BASE} --no-read --no-write #{FIXTURES}"
7
+
8
+ it "must not produce help wider than 80 characters" do
9
+ `#{BASE} -h`.each_line do |line|
10
+ line.length.must_be :<=, 80
11
+ end
12
+ end
13
+
14
+ it "must produce the right version" do
15
+ `#{BASE} -v`.chomp.must_equal Starscope::VERSION
16
+ end
17
+
18
+ it "must produce a valid database summary" do
19
+ lines = `#{EXTRACT} -s`.lines.to_a
20
+ lines.length.must_equal 6
21
+ end
22
+
23
+ it "must produce a valid database dump" do
24
+ lines = `#{EXTRACT} -d requires`.lines.to_a
25
+ lines[1].split.first.must_equal 'date'
26
+ lines[2].split.first.must_equal 'zlib'
27
+ end
28
+
29
+ it "must correctly query the database" do
30
+ `#{EXTRACT} -q calls,add_file`.each_line do |line|
31
+ line.split[0..2].must_equal ["Starscope", "DB", "add_file"]
32
+ end
33
+ end
34
+
35
+ it "must correctly export to cscope" do
36
+ file = Tempfile.new('starscope_test')
37
+ begin
38
+ `#{EXTRACT} -e cscope,#{file.path()}`
39
+ $?.exitstatus.must_equal 0
40
+ ensure
41
+ file.close
42
+ file.unlink
43
+ end
44
+ end
45
+
46
+ it "Must correctly export to ctags" do
47
+ file = Tempfile.new('starscope_test')
48
+ begin
49
+ `#{EXTRACT} -e ctags,#{file.path()}`
50
+ $?.exitstatus.must_equal 0
51
+ ensure
52
+ file.close
53
+ file.unlink
54
+ end
55
+ end
56
+
57
+ end
data/test/test_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'minitest/autorun'
2
2
  require 'minitest/pride'
3
+ require 'mocha/mini_test'
3
4
  require File.expand_path('../../lib/starscope.rb', __FILE__)
4
5
 
5
6
  FIXTURES="test/fixtures"
@@ -0,0 +1,141 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+ require 'tempfile'
3
+
4
+ describe Starscope::DB do
5
+
6
+ before do
7
+ @db = Starscope::DB.new(Starscope::Output.new(:quiet))
8
+ end
9
+
10
+ it "must raise on invalid tables" do
11
+ proc {
12
+ @db.records(:foo)
13
+ }.must_raise Starscope::DB::NoTableError
14
+ end
15
+
16
+ it "must add paths" do
17
+ paths = [GOLANG_SAMPLE, "#{FIXTURES}/**/*"]
18
+ @db.add_paths(paths)
19
+
20
+ @db.metadata(:paths).must_equal paths
21
+ validate(@db)
22
+ end
23
+
24
+ it "must add excludes" do
25
+ paths = [GOLANG_SAMPLE, "#{FIXTURES}/**/*"]
26
+ @db.add_paths(paths)
27
+ @db.add_excludes(["#{FIXTURES}/**"])
28
+
29
+ files = @db.metadata(:files).keys
30
+ files.wont_include RUBY_SAMPLE
31
+ files.wont_include GOLANG_SAMPLE
32
+ @db.records(:defs).must_be_empty
33
+ @db.records(:end).must_be_empty
34
+ end
35
+
36
+ it "must pick up new files in old paths" do
37
+ @db.load("#{FIXTURES}/db_added_files.json")
38
+ @db.update
39
+
40
+ validate(@db)
41
+ end
42
+
43
+ it "must remove old files in existing paths" do
44
+ @db.load("#{FIXTURES}/db_removed_files.json")
45
+ @db.update
46
+ @db.metadata(:files).keys.wont_include "#{FIXTURES}/foo"
47
+ end
48
+
49
+ it "must update stale existing files when extractor hasn't changed" do
50
+ @db.load("#{FIXTURES}/db_out_of_date.json")
51
+ @db.metadata(:langs)[:Go].must_be :>=, LANGS[:Go]
52
+
53
+ cur_mtime = @db.metadata(:files)[GOLANG_SAMPLE][:last_updated]
54
+ File.expects(:mtime).twice.returns(cur_mtime + 1)
55
+ @db.update
56
+
57
+ file = @db.metadata(:files)[GOLANG_SAMPLE]
58
+ file[:last_updated].must_equal cur_mtime + 1
59
+ file[:lang].must_equal :Go
60
+ file[:lines].wont_be_empty
61
+ @db.records(:defs).wont_be_empty
62
+ @db.records(:calls).wont_be_empty
63
+ end
64
+
65
+ it "must update unchanged existing files with old extractor versions" do
66
+ @db.load("#{FIXTURES}/db_old_extractor.json")
67
+
68
+ cur_mtime = @db.metadata(:files)[GOLANG_SAMPLE][:last_updated]
69
+ File.expects(:mtime).twice.returns(cur_mtime)
70
+ @db.update
71
+
72
+ file = @db.metadata(:files)[GOLANG_SAMPLE]
73
+ file[:last_updated].must_equal cur_mtime
74
+ file[:lang].must_equal :Go
75
+ file[:lines].wont_be_empty
76
+ @db.records(:defs).wont_be_empty
77
+ @db.records(:calls).wont_be_empty
78
+ end
79
+
80
+ it "must not update file with up-to-date time and extractor" do
81
+ @db.load("#{FIXTURES}/db_up_to_date.json")
82
+ @db.update
83
+
84
+ file = @db.metadata(:files)[GOLANG_SAMPLE]
85
+ file[:last_updated].must_equal 10000000000
86
+ @db.tables.must_be_empty
87
+ end
88
+
89
+ it "must load an old DB file" do
90
+ @db.load("#{FIXTURES}/db_old.json.gz")
91
+ @db.metadata(:paths).must_equal ["#{FIXTURES}/**/*"]
92
+ validate(@db)
93
+ end
94
+
95
+ it "must round-trip a database" do
96
+ file = Tempfile.new('starscope_test')
97
+ begin
98
+ @db.add_paths([FIXTURES])
99
+ @db.save(file.path)
100
+ tmp = Starscope::DB.new(Starscope::Output.new(:quiet))
101
+ tmp.load(file.path)
102
+ validate(tmp)
103
+ ensure
104
+ file.close
105
+ file.unlink
106
+ end
107
+ end
108
+
109
+ it "must run queries" do
110
+ @db.add_paths([FIXTURES])
111
+ @db.query(:calls, "abc").must_equal []
112
+ @db.query(:defs, "xyz").must_equal []
113
+ @db.query(:calls, "add_file").length.must_equal 3
114
+ end
115
+
116
+ it "must symbolize compound name" do
117
+ rec = Starscope::DB.normalize_record(:foo, ["a", :b], {})
118
+ rec[:name].must_equal [:a, :b]
119
+ end
120
+
121
+ it "must symbolize and array-wrap simple name" do
122
+ rec = Starscope::DB.normalize_record(:foo, "a", {})
123
+ rec[:name].must_equal [:a]
124
+ end
125
+
126
+ private
127
+
128
+ def validate(db)
129
+ files = db.metadata(:files)
130
+ files.keys.must_include GOLANG_SAMPLE
131
+ files.keys.must_include RUBY_SAMPLE
132
+ files[GOLANG_SAMPLE][:last_updated].must_equal File.mtime(GOLANG_SAMPLE).to_i
133
+ files[RUBY_SAMPLE][:last_updated].must_equal File.mtime(RUBY_SAMPLE).to_i
134
+
135
+ db.records(:defs).wont_be_empty
136
+ db.records(:calls).wont_be_empty
137
+ db.records(:imports).wont_be_empty
138
+ db.records(:requires).wont_be_empty
139
+ end
140
+
141
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ describe Starscope::Export do
4
+
5
+ before do
6
+ @db = Starscope::DB.new(Starscope::Output.new(:quiet))
7
+ @db.add_paths([FIXTURES])
8
+ @buf = StringIO.new
9
+ end
10
+
11
+ it "must export to ctags" do
12
+ @db.export_to(:ctags, @buf)
13
+ @buf.rewind
14
+ lines = @buf.lines.to_a
15
+ lines.must_include "NoTableError\t#{FIXTURES}/sample_ruby.rb\t/^ class NoTableError < StandardError; end$/;\"\tkind:c\tlanguage:Ruby\n"
16
+ end
17
+
18
+ it "must export to cscope" do
19
+ @db.export_to(:cscope, @buf)
20
+ @buf.rewind
21
+ lines = @buf.lines.to_a
22
+
23
+ lines.must_include "\t@#{FIXTURES}/sample_golang.go\n"
24
+ lines.must_include "\tgSunday\n"
25
+ lines.must_include "\t`add_file\n"
26
+ lines.must_include "\t}}\n"
27
+ lines.must_include "13 class \n"
28
+
29
+ lines.wont_include "= [\n"
30
+ lines.wont_include "4 LANGS = [\n"
31
+ lines.wont_include "116 tmpdb[entry[:file]][entry[:line_no]] ||= []\n"
32
+ end
33
+
34
+ end