starscope 1.1.2 → 1.2.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.
@@ -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