stickyflag 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +4 -0
  3. data/.simplecov +9 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE.md +7 -0
  7. data/README.md +49 -0
  8. data/Rakefile +19 -0
  9. data/TODO.md +3 -0
  10. data/bin/stickyflag +6 -0
  11. data/features/clear.feature +14 -0
  12. data/features/clear_quietly.feature +23 -0
  13. data/features/configuration.feature +14 -0
  14. data/features/get.feature +14 -0
  15. data/features/get_quietly.feature +23 -0
  16. data/features/set.feature +14 -0
  17. data/features/set_quietly.feature +22 -0
  18. data/features/step_definitions/configuration_steps.rb +31 -0
  19. data/features/step_definitions/database_steps.rb +41 -0
  20. data/features/step_definitions/pending_steps.rb +5 -0
  21. data/features/step_definitions/tag_steps.rb +62 -0
  22. data/features/support/cukegem.rb +82 -0
  23. data/features/support/env.rb +37 -0
  24. data/features/tags.feature +18 -0
  25. data/features/unset.feature +14 -0
  26. data/features/unset_quietly.feature +23 -0
  27. data/lib/stickyflag/configuration.rb +66 -0
  28. data/lib/stickyflag/database.rb +162 -0
  29. data/lib/stickyflag/external_cmds.rb +64 -0
  30. data/lib/stickyflag/patches/tempfile_encoding.rb +22 -0
  31. data/lib/stickyflag/patches/tmpnam.rb +38 -0
  32. data/lib/stickyflag/paths.rb +47 -0
  33. data/lib/stickyflag/tag_factory.rb +108 -0
  34. data/lib/stickyflag/tags/c.rb +25 -0
  35. data/lib/stickyflag/tags/mmd.rb +168 -0
  36. data/lib/stickyflag/tags/pdf.rb +119 -0
  37. data/lib/stickyflag/tags/png.rb +61 -0
  38. data/lib/stickyflag/tags/source_code.rb +99 -0
  39. data/lib/stickyflag/tags/tex.rb +25 -0
  40. data/lib/stickyflag/version.rb +12 -0
  41. data/lib/stickyflag.rb +253 -0
  42. data/spec/spec_helper.rb +22 -0
  43. data/spec/stickyflag/configuration_spec.rb +132 -0
  44. data/spec/stickyflag/database_spec.rb +331 -0
  45. data/spec/stickyflag/external_cmds_spec.rb +175 -0
  46. data/spec/stickyflag/patches/tempfile_encoding_spec.rb +26 -0
  47. data/spec/stickyflag/patches/tmpnam_spec.rb +35 -0
  48. data/spec/stickyflag/paths_spec.rb +29 -0
  49. data/spec/stickyflag/tag_factory_spec.rb +185 -0
  50. data/spec/stickyflag/tags/c_spec.rb +14 -0
  51. data/spec/stickyflag/tags/mmd_spec.rb +40 -0
  52. data/spec/stickyflag/tags/pdf_spec.rb +39 -0
  53. data/spec/stickyflag/tags/png_spec.rb +6 -0
  54. data/spec/stickyflag/tags/tex_spec.rb +6 -0
  55. data/spec/stickyflag_spec.rb +482 -0
  56. data/spec/support/examples/c_all_comments.c +3 -0
  57. data/spec/support/examples/c_no_tags.c +5 -0
  58. data/spec/support/examples/c_with_tag.c +6 -0
  59. data/spec/support/examples/mmd_all_meta.mmd +6 -0
  60. data/spec/support/examples/mmd_crazy_keys.mmd +8 -0
  61. data/spec/support/examples/mmd_crazy_tags.mmd +9 -0
  62. data/spec/support/examples/mmd_no_tags.mmd +1 -0
  63. data/spec/support/examples/mmd_with_tag.mmd +3 -0
  64. data/spec/support/examples/pdf_no_tags.pdf +0 -0
  65. data/spec/support/examples/pdf_with_tag.pdf +0 -0
  66. data/spec/support/examples/png_no_tags.png +0 -0
  67. data/spec/support/examples/png_with_tag.png +0 -0
  68. data/spec/support/examples/tex_no_tags.tex +10 -0
  69. data/spec/support/examples/tex_with_tag.tex +11 -0
  70. data/spec/support/examples/untaggable.txt +0 -0
  71. data/spec/support/examples.rb +32 -0
  72. data/spec/support/run_with_args.rb +36 -0
  73. data/spec/support/silence_stream.rb +12 -0
  74. data/spec/support/tag_handler_behavior.rb +125 -0
  75. data/stickyflag.gemspec +48 -0
  76. metadata +399 -0
@@ -0,0 +1,29 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'stickyflag/paths'
3
+
4
+ class PathsTester
5
+ include StickyFlag::Paths
6
+ end
7
+
8
+ describe 'StickyFlag::Paths' do
9
+ describe '.config_path' do
10
+ it 'includes the config.yml file name' do
11
+ PathsTester.new.config_path.should include('config.yml')
12
+ end
13
+
14
+ it "doesn't include any tildes" do
15
+ PathsTester.new.config_path.should_not include('~')
16
+ end
17
+ end
18
+
19
+ describe '.database_path' do
20
+ it 'includes the db.sqlite file name' do
21
+ PathsTester.new.database_path.should include('db.sqlite')
22
+ end
23
+
24
+ it "doesn't include any tildes" do
25
+ PathsTester.new.database_path.should_not include('~')
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,185 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'thor'
3
+ require 'stickyflag/patches/tempfile_encoding'
4
+ require 'stickyflag/paths'
5
+ require 'stickyflag/configuration'
6
+ require 'stickyflag/tag_factory'
7
+ require 'stickyflag/external_cmds'
8
+ require 'stickyflag/database'
9
+
10
+ class TagFactoryTester < Thor
11
+ include StickyFlag::Paths
12
+ include StickyFlag::Configuration
13
+ include StickyFlag::TagFactory
14
+ include StickyFlag::ExternalCmds
15
+ include StickyFlag::Database
16
+ end
17
+
18
+ describe 'StickyFlag::TagFactory' do
19
+ before(:each) do
20
+ @obj = TagFactoryTester.new
21
+
22
+ @obj.stub(:load_config!) { }
23
+ @obj.stub(:save_config!) { }
24
+
25
+ @obj.stub(:load_database) { }
26
+ @obj.stub(:update_database_from_files) { }
27
+ @obj.stub(:set_database_tag) { }
28
+ @obj.stub(:unset_database_tag) { }
29
+ @obj.stub(:clear_database_tags) { }
30
+ @obj.stub(:files_for_tags) { [] }
31
+
32
+ @obj.find_external_cmds
33
+ end
34
+
35
+ describe '.available_tagging_extensions' do
36
+ # Some extensions require the presence of actual, good files, not
37
+ # just empty shells, so we can't test them in this way. Skip those.
38
+ CANNOT_TEST = [ '.pdf', '.png' ]
39
+
40
+ it 'should call get for every good extension' do
41
+ (@obj.available_tagging_extensions - CANNOT_TEST).each do |ext|
42
+ file = Tempfile.new_with_encoding(['ext', ext])
43
+ file.puts('test')
44
+ file.close
45
+
46
+ expect { @obj.get_tags_for(file.path) }.to_not raise_error
47
+ file.unlink
48
+ end
49
+ end
50
+
51
+ it 'should call get for other extensions' do
52
+ CANNOT_TEST.each do |ext|
53
+ path = copy_example "#{ext[1..-1]}_with_tag#{ext}"
54
+ expect { @obj.clear_tags_for(path) }.to_not raise_error
55
+ File.unlink(path)
56
+ end
57
+ end
58
+
59
+ it 'should call set/unset for every good extension' do
60
+ (@obj.available_tagging_extensions - CANNOT_TEST).each do |ext|
61
+ file = Tempfile.new_with_encoding(['ext', ext])
62
+ file.puts('test')
63
+ file.close
64
+
65
+ expect {
66
+ @obj.set_tag_for(file.path, 'test')
67
+ @obj.unset_tag_for(file.path, 'test')
68
+ }.to_not raise_error
69
+ file.unlink
70
+ end
71
+ end
72
+
73
+ it 'should call set/unset for other extensions' do
74
+ CANNOT_TEST.each do |ext|
75
+ path = copy_example "#{ext[1..-1]}_with_tag#{ext}"
76
+ expect {
77
+ @obj.set_tag_for(path, 'test2')
78
+ @obj.unset_tag_for(path, 'test2')
79
+ }.to_not raise_error
80
+ File.unlink(path)
81
+ end
82
+ end
83
+
84
+ it 'should call clear for every good extension' do
85
+ (@obj.available_tagging_extensions - CANNOT_TEST).each do |ext|
86
+ file = Tempfile.new_with_encoding(['ext', ext])
87
+ file.puts('test')
88
+ file.close
89
+
90
+ expect { @obj.clear_tags_for(file.path) }.to_not raise_error
91
+ file.unlink
92
+ end
93
+ end
94
+
95
+ it 'should call clear for other extensions' do
96
+ CANNOT_TEST.each do |ext|
97
+ path = copy_example "#{ext[1..-1]}_with_tag#{ext}"
98
+ expect { @obj.clear_tags_for(path) }.to_not raise_error
99
+ File.unlink(path)
100
+ end
101
+ end
102
+ end
103
+
104
+ describe '.get_tags_for' do
105
+ it 'should delegate to PDF' do
106
+ path = example_path('pdf_no_tags.pdf')
107
+
108
+ StickyFlag::Tags::PDF.should_receive(:get).with(path, kind_of(String))
109
+ @obj.get_tags_for(path)
110
+ end
111
+
112
+ it 'should raise error for unknown extensions' do
113
+ expect {
114
+ @obj.get_tags_for('asdf.zzy')
115
+ }.to raise_error(Thor::Error)
116
+ end
117
+ end
118
+
119
+ describe '.set_tag_for' do
120
+ it 'should delegate to PDF' do
121
+ path = example_path('pdf_no_tags.pdf')
122
+
123
+ StickyFlag::Tags::PDF.should_receive(:set).with(path, 'lol', kind_of(String))
124
+ @obj.set_tag_for(path, 'lol')
125
+ end
126
+
127
+ it 'should not call through if the tag is already set' do
128
+ path = example_path('pdf_with_tag.pdf')
129
+
130
+ StickyFlag::Tags::PDF.should_not_receive(:set)
131
+ @obj.set_tag_for(path, 'test')
132
+ end
133
+
134
+ it 'should raise error for unknown extensions' do
135
+ @obj.stub(:get_tags_for) { [] }
136
+ expect {
137
+ @obj.set_tag_for('asdf.zzy', 'lol')
138
+ }.to raise_error(Thor::Error)
139
+ end
140
+ end
141
+
142
+ describe '.unset_tag_for' do
143
+ it 'should delegate to PDF' do
144
+ path = copy_example('pdf_with_tag.pdf')
145
+
146
+ StickyFlag::Tags::PDF.should_receive(:unset).with(path, 'test', kind_of(String))
147
+ @obj.unset_tag_for(path, 'test')
148
+
149
+ File.delete(path)
150
+ end
151
+
152
+ it 'should not call through if the tag is not set' do
153
+ path = example_path('pdf_no_tags.pdf')
154
+
155
+ StickyFlag::Tags::PDF.should_not_receive(:unset)
156
+ expect {
157
+ @obj.unset_tag_for(path, 'test')
158
+ }.to raise_error(Thor::Error)
159
+ end
160
+
161
+ it 'should raise error for unknown extensions' do
162
+ @obj.stub(:get_tags_for) { [ 'lol' ] }
163
+ expect {
164
+ @obj.unset_tag_for('asdf.zzy', 'lol')
165
+ }.to raise_error(Thor::Error)
166
+ end
167
+ end
168
+
169
+ describe '.clear_tags_for' do
170
+ it 'should delegate to PDF' do
171
+ path = copy_example('pdf_with_tag.pdf')
172
+
173
+ StickyFlag::Tags::PDF.should_receive(:clear).with(path, kind_of(String))
174
+ @obj.clear_tags_for(path)
175
+
176
+ File.delete(path)
177
+ end
178
+
179
+ it 'should raise error for unknown extensions' do
180
+ expect {
181
+ @obj.clear_tags_for('asdf.zzy')
182
+ }.to raise_error(Thor::Error)
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'stickyflag/tags/c'
3
+
4
+ describe StickyFlag::Tags::C do
5
+ it_behaves_like 'a tag handler'
6
+
7
+ it 'can open a file with all comments and no tags' do
8
+ ret = nil
9
+ expect {
10
+ ret = StickyFlag::Tags::C.get(example_path('c_all_comments.c'))
11
+ }.to_not raise_error
12
+ ret.should be_empty
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'stickyflag/tags/mmd'
3
+
4
+ describe StickyFlag::Tags::MMD do
5
+ it_behaves_like 'a tag handler'
6
+
7
+ it 'handles multiline metadata documents' do
8
+ StickyFlag::Tags::MMD.get(example_path('mmd_crazy_keys.mmd')).should include('test')
9
+ end
10
+
11
+ it 'handles multiline tag documents' do
12
+ StickyFlag::Tags::MMD.get(example_path('mmd_crazy_tags.mmd')).should include('sdfg')
13
+ end
14
+
15
+ it 'handles all-metadata documents' do
16
+ StickyFlag::Tags::MMD.get(example_path('mmd_all_meta.mmd')).should be_empty
17
+ end
18
+
19
+ it 'can edit multiline metadata documents' do
20
+ path = copy_example('mmd_crazy_keys.mmd')
21
+
22
+ StickyFlag::Tags::MMD.set(path, 'test2')
23
+ StickyFlag::Tags::MMD.get(path).should include('test2')
24
+
25
+ File.open(path, 'r:UTF-8').each_line.to_a.should include("Tags: test, test2 \n")
26
+
27
+ File.delete path
28
+ end
29
+
30
+ it 'can edit multiline tag documents' do
31
+ path = copy_example('mmd_crazy_tags.mmd')
32
+
33
+ StickyFlag::Tags::MMD.set(path, 'test2')
34
+ StickyFlag::Tags::MMD.get(path).should include('test2')
35
+
36
+ File.open(path, 'r:UTF-8').each_line.to_a.should include("Tags: asdf, sdfg, dfgh, fghj, qwer, test2 \n")
37
+
38
+ File.delete path
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'stickyflag/tags/pdf'
3
+ require 'stickyflag/paths'
4
+ require 'stickyflag/configuration'
5
+ require 'stickyflag/external_cmds'
6
+
7
+ class GetConfiguration
8
+ include StickyFlag::Paths
9
+ include StickyFlag::Configuration
10
+ include StickyFlag::ExternalCmds
11
+ end
12
+
13
+ describe StickyFlag::Tags::PDF do
14
+ it_behaves_like 'a tag handler' do
15
+ let(:params) {
16
+ config = GetConfiguration.new
17
+ config.stub(:load_config!) { }
18
+ config.stub(:save_config!) { }
19
+
20
+ config.find_external_cmds
21
+
22
+ [ config.get_config(:pdftk_path) ]
23
+ }
24
+ end
25
+
26
+ context 'with a bad pdftk path' do
27
+ it 'raises errors for everything' do
28
+ expect { StickyFlag::Tags::PDF.get(example_path("pdf_with_tag.pdf"), '/wut/bad') }.to raise_error(Thor::Error)
29
+ expect { StickyFlag::Tags::PDF.clear(example_path("pdf_with_tag.pdf"), '/wut/bad') }.to raise_error(Thor::Error)
30
+
31
+ # If get doesn't succeed, we won't get all the way into set or unset
32
+ # with the bad pdftk path.
33
+ StickyFlag::Tags::PDF.stub(:get) { [ 'test' ] }
34
+ expect { StickyFlag::Tags::PDF.set(example_path("pdf_with_tag.pdf"), 'test2', '/wut/bad') }.to raise_error(Thor::Error)
35
+ expect { StickyFlag::Tags::PDF.unset(example_path("pdf_with_tag.pdf"), 'test', '/wut/bad') }.to raise_error(Thor::Error)
36
+ StickyFlag::Tags::PDF.unstub(:get)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'stickyflag/tags/png'
3
+
4
+ describe StickyFlag::Tags::PNG do
5
+ it_behaves_like 'a tag handler'
6
+ end
@@ -0,0 +1,6 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'stickyflag/tags/tex'
3
+
4
+ describe StickyFlag::Tags::TeX do
5
+ it_behaves_like 'a tag handler'
6
+ end