weft-qda 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/lib/weft.rb +21 -0
  2. data/lib/weft/WEFT-VERSION-STRING.rb +1 -0
  3. data/lib/weft/application.rb +130 -0
  4. data/lib/weft/backend.rb +39 -0
  5. data/lib/weft/backend/marshal.rb +26 -0
  6. data/lib/weft/backend/mysql.rb +267 -0
  7. data/lib/weft/backend/n6.rb +366 -0
  8. data/lib/weft/backend/sqlite.rb +633 -0
  9. data/lib/weft/backend/sqlite/category_tree.rb +104 -0
  10. data/lib/weft/backend/sqlite/schema.rb +152 -0
  11. data/lib/weft/backend/sqlite/upgradeable.rb +55 -0
  12. data/lib/weft/category.rb +157 -0
  13. data/lib/weft/coding.rb +355 -0
  14. data/lib/weft/document.rb +118 -0
  15. data/lib/weft/filters.rb +243 -0
  16. data/lib/weft/wxgui.rb +687 -0
  17. data/lib/weft/wxgui/category.xpm +26 -0
  18. data/lib/weft/wxgui/dialogs.rb +128 -0
  19. data/lib/weft/wxgui/document.xpm +25 -0
  20. data/lib/weft/wxgui/error_handler.rb +52 -0
  21. data/lib/weft/wxgui/inspectors.rb +361 -0
  22. data/lib/weft/wxgui/inspectors/category.rb +165 -0
  23. data/lib/weft/wxgui/inspectors/codereview.rb +275 -0
  24. data/lib/weft/wxgui/inspectors/document.rb +139 -0
  25. data/lib/weft/wxgui/inspectors/imagedocument.rb +56 -0
  26. data/lib/weft/wxgui/inspectors/script.rb +35 -0
  27. data/lib/weft/wxgui/inspectors/search.rb +265 -0
  28. data/lib/weft/wxgui/inspectors/textcontrols.rb +304 -0
  29. data/lib/weft/wxgui/lang.rb +17 -0
  30. data/lib/weft/wxgui/lang/en.rb +45 -0
  31. data/lib/weft/wxgui/mondrian.xpm +44 -0
  32. data/lib/weft/wxgui/search.xpm +25 -0
  33. data/lib/weft/wxgui/sidebar.rb +498 -0
  34. data/lib/weft/wxgui/utilities.rb +148 -0
  35. data/lib/weft/wxgui/weft16.xpm +31 -0
  36. data/lib/weft/wxgui/workarea.rb +249 -0
  37. data/test/001-document.rb +196 -0
  38. data/test/002-category.rb +138 -0
  39. data/test/003-code.rb +370 -0
  40. data/test/004-application.rb +52 -0
  41. data/test/006-filters.rb +139 -0
  42. data/test/009a-backend_sqlite_basic.rb +280 -0
  43. data/test/009b-backend_sqlite_complex.rb +175 -0
  44. data/test/009c_backend_sqlite_bench.rb +81 -0
  45. data/test/010-backend_nudist.rb +5 -0
  46. data/test/all-tests.rb +1 -0
  47. data/test/manual-gui-script.txt +24 -0
  48. data/test/testdata/autocoding-test.txt +15 -0
  49. data/test/testdata/iso-8859-1.txt +5 -0
  50. data/test/testdata/sample_doc.txt +19 -0
  51. data/test/testdata/search_results.txt +1254 -0
  52. data/test/testdata/text1-dos-ascii.txt +2 -0
  53. data/test/testdata/text1-unix-utf8.txt +2 -0
  54. data/weft-qda.rb +28 -0
  55. metadata +96 -0
@@ -0,0 +1,52 @@
1
+ $:.push('../lib/')
2
+
3
+ require 'weft/application'
4
+ require 'test/unit'
5
+
6
+ class DummyClient
7
+ attr_reader :state_display
8
+
9
+ def initialize(app = nil)
10
+ app.add_observer(self) if app
11
+ @state_display = "CLEAN"
12
+ end
13
+
14
+ def update(state)
15
+ @state_display = state ? "DIRTY" : "CLEAN"
16
+ end
17
+ end
18
+
19
+ class TestApplication < Test::Unit::TestCase
20
+ def setup
21
+
22
+ end
23
+
24
+ def test_basic
25
+ app = QDA::Application.new()
26
+ client = DummyClient.new(app)
27
+ assert_equal("CLEAN", client.state_display,
28
+ "Observer initially set to show clean")
29
+ app.dirty!
30
+ assert_equal("DIRTY", client.state_display,
31
+ "Observer picks up dirtying")
32
+ app.undirty!
33
+ assert_equal("CLEAN", client.state_display,
34
+ "Observer picks up saving")
35
+
36
+ end
37
+
38
+ def test_basic_w_initializer
39
+ client = DummyClient.new()
40
+ app = QDA::Application.new(client)
41
+
42
+ assert_equal("CLEAN", client.state_display,
43
+ "Observer initially set to show clean")
44
+ app.dirty!
45
+ assert_equal("DIRTY", client.state_display,
46
+ "Observer picks up dirtying")
47
+ app.undirty!
48
+ assert_equal("CLEAN", client.state_display,
49
+ "Observer picks up saving")
50
+
51
+ end
52
+ end
@@ -0,0 +1,139 @@
1
+ require 'english'
2
+
3
+ $:.push('../lib/')
4
+
5
+ require 'weft/application'
6
+ require 'weft/backend'
7
+ require 'weft/document'
8
+ require 'weft/filters'
9
+
10
+ require 'test/unit'
11
+
12
+ class TestFilter < Test::Unit::TestCase
13
+ def sample_file(filename)
14
+ File.join( File.dirname( __FILE__), 'testdata', filename)
15
+ end
16
+
17
+ def test_unix_utf8()
18
+ filter = QDA::TextFilter.new()
19
+ doc = filter.read(sample_file('text1-unix-utf8.txt'), 'test-unix-utf8')
20
+
21
+ str = "This is a text document\nin unix unicode.\n"
22
+ assert_equal(str, doc.text, "Document text read in")
23
+ end
24
+
25
+ def test_indexer
26
+ idx = QDA::Indexer.new()
27
+ idx.index('foo')
28
+
29
+ widx = QDA::WordIndexer.new()
30
+ my_word = 'SOMETHING'
31
+ widx.index(my_word)
32
+ assert_equal(1, widx.words.keys.length)
33
+ assert_equal(1, widx.words[my_word].length)
34
+ end
35
+
36
+ def test_dos_ascii()
37
+ filter = QDA::TextFilter.new()
38
+ doc = filter.read(sample_file('text1-dos-ascii.txt'), 'test-ascii')
39
+
40
+ str = "This is a text document\nin dos ascii.\n"
41
+ assert_equal(str, doc.text, "Document text read in")
42
+ end
43
+
44
+ def test_pdf
45
+ filter = QDA::PDFFilter.new()
46
+ windxr = QDA::WordIndexer.new()
47
+ filter.add_indexer(windxr)
48
+ doc = filter.read('testdata/emacs-refcard-a4.pdf', 'i')
49
+
50
+ doc.title = 'Acknowledgments'
51
+ word = 'moving'
52
+ windxr.words.each do | word, offsets |
53
+ offsets.each do | offset |
54
+ assert_equal( word, doc[offset, word.length] )
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_word_indexing()
60
+ filter = QDA::TextFilter.new()
61
+ windxr = QDA::WordIndexer.new()
62
+ filter.add_indexer(windxr)
63
+ doc = filter.read(sample_file('autocoding-test.txt'),
64
+ 'word_indexing')
65
+ # ordinary, capitalised, short, apostrophe, longer
66
+ test_words = [ 'the', 'Before', 'I', 'It\'s', 'opinions' ]
67
+ test_words.each do | test_word |
68
+ windxr.words[test_word].each do | loc |
69
+ assert_equal(test_word, doc.text[loc, test_word.length].to_s)
70
+ end
71
+ end
72
+ end
73
+
74
+ def test_indexing_iso_8859_1
75
+ filter = QDA::TextFilter.new()
76
+ windxr = QDA::WordIndexer.new()
77
+ filter.add_indexer(windxr)
78
+ doc = filter.read(sample_file('iso-8859-1.txt'), 'iso-8859-1')
79
+ word_rx = /[\w\xC0-\xD6\xD8-\xF6\xF8-\xFF][\w\xC0-\xD6\xD8-\xF6\xF8-\xFF\']+/
80
+ windxr.words.each_key do | word |
81
+ assert_match(word_rx, word)
82
+ end
83
+ end
84
+
85
+ def test_autocoding
86
+ filter = QDA::TextFilter.new()
87
+ autocoder = QDA::AutoCoder.new(/^\*\*(.*)\*\*\s*$/ => 'Heading',
88
+ /^(.*)\:\s*$/ => 'Speaker')
89
+ filter.add_indexer(autocoder)
90
+
91
+ doc = filter.read(sample_file('autocoding-test.txt'),
92
+ 'autocoding')
93
+
94
+ str = "Before any autocoding\n\nSpeakerA:\nI am the first speaker.\nThis is what I say.\n\n**A TEXT HEADER**\n\nSpeakerB:\nI am the second speaker.\n\nThis is what I say. It's my opinions.\n\nSpeakerA:\nMe again.\n"
95
+ assert_equal(str, doc.text)
96
+ autocodes = autocoder.codes
97
+ assert_equal(2, autocodes.keys.length,
98
+ "Number of autocode types created")
99
+
100
+ speaker_a = autocodes['Speaker']['SpeakerA']
101
+ assert_instance_of(QDA::CodeSet, speaker_a,
102
+ "Autocode speaker A category created")
103
+ assert_equal(2, speaker_a.length, "Multiple passages coded")
104
+ # assert_equal(1, speaker_a.num_of_docs, "Single document coded")
105
+ content_a_1 =
106
+ "SpeakerA:
107
+ I am the first speaker.
108
+ This is what I say.
109
+
110
+ **A TEXT HEADER**
111
+
112
+ "
113
+ assert_equal(content_a_1,
114
+ doc.text[speaker_a[0].offset, speaker_a[0].length],
115
+ "Document text retrievable by code" )
116
+
117
+ speaker_b = autocodes['Speaker']['SpeakerB']
118
+ assert_instance_of(QDA::CodeSet, speaker_b,
119
+ "Autocode speaker B category created")
120
+
121
+ heading_1 = autocodes['Heading']['A TEXT HEADER']
122
+ assert_instance_of(QDA::CodeSet, heading_1,
123
+ "Autocode heading category created")
124
+
125
+ header_extract = "**A TEXT HEADER**
126
+
127
+ SpeakerB:
128
+ I am the second speaker.
129
+
130
+ This is what I say. It's my opinions.
131
+
132
+ SpeakerA:
133
+ Me again.
134
+ "
135
+ assert_equal(header_extract,
136
+ doc.text[heading_1[0].offset, heading_1[0].length],
137
+ "Document text retrievable by code" )
138
+ end
139
+ end
@@ -0,0 +1,280 @@
1
+ require 'english'
2
+ $:.push('../lib/')
3
+
4
+ require 'weft'
5
+ require 'test/unit'
6
+
7
+ class TestSQLiteBasic < Test::Unit::TestCase
8
+ def sample_file(filename)
9
+ File.join( File.dirname( __FILE__), 'testdata', filename)
10
+ end
11
+
12
+ def setup
13
+ @dbfile = nil
14
+ @app = QDA::Application.new()
15
+ @app.extend(QDA::Backend::SQLite)
16
+ end
17
+
18
+ # delete any files hanging around
19
+ def teardown()
20
+ if @app.started?
21
+ # p @app
22
+ # @app.end()
23
+ if @app.dbfile and File.exist?(@app.dbfile)
24
+ File.delete(@app.dbfile)
25
+ end
26
+ end
27
+ end
28
+
29
+ # test save & revert
30
+ def test_statefulness
31
+ @app.start(:dbfile => @dbfile)
32
+ @app.install_clean()
33
+ doc = QDA::Document.new('Doc-1')
34
+ @app.save_document(doc)
35
+
36
+ assert_raises(RuntimeError, "Cannot save without a filename") do
37
+ doc = @app.save()
38
+ end
39
+
40
+ @dbfile = 'foo.db'
41
+
42
+ @app.save(@dbfile)
43
+ assert(File.exist?(@dbfile), "File created after save")
44
+ assert(@app.get_doc('Doc-1'), "Still has saved content - new filename")
45
+
46
+ doc = QDA::Document.new('Doc-2')
47
+ @app.save_document(doc)
48
+ @app.save
49
+ assert(@app.get_doc('Doc-2'), "Still has saved content - re-use filename")
50
+
51
+ doc = QDA::Document.new('Doc-3')
52
+ @app.save_document(doc)
53
+ @app.revert
54
+ assert(File.exist?(@dbfile), "File exists after revert")
55
+
56
+ assert(@app.get_doc('Doc-1'), "Still has last-saved content")
57
+ assert(@app.get_doc('Doc-2'), "Still has last-saved content")
58
+ assert_raises(RuntimeError, "Lost unsaved content") do
59
+ doc = @app.get_doc('Doc-3')
60
+ end
61
+ end
62
+
63
+ def test_open_file
64
+ @app.start(:dbfile => @dbfile)
65
+ @app.install_clean()
66
+ @app.set_up()
67
+
68
+ # this will save in current working directory
69
+ @app.save('foo.db')
70
+ @app.end
71
+
72
+ @app.start(:dbfile => File::join(Dir.pwd, 'foo.db') )
73
+ File.unlink(File::join(Dir.pwd, 'foo.db'))
74
+ end
75
+
76
+ def test_basic_save_and_get_document()
77
+ @app.start(:dbfile => @dbfile)
78
+ @app.install_clean()
79
+ doc = QDA::Document.new('About Something')
80
+ assert_nil(doc.dbid, "No DBID set")
81
+ @app.save_document(doc)
82
+ assert(doc.dbid, 'Got a DBID set')
83
+
84
+ fetch_doc = @app.get_doc(doc.dbid)
85
+ assert(fetch_doc, "Got something back")
86
+
87
+ assert_equal(doc.dbid, fetch_doc.dbid,
88
+ "Fetched back thing has the same dbid")
89
+ assert_equal(doc.title, fetch_doc.title,
90
+ "Fetched back thing has the same dbid")
91
+
92
+ fetch_doc = @app.get_doc(doc.title)
93
+ assert(fetch_doc, "Got something back")
94
+
95
+ assert_equal(doc.dbid, fetch_doc.dbid,
96
+ "Fetched back thing has the same dbid")
97
+ assert_equal(doc.title, fetch_doc.title,
98
+ "Fetched back thing has the same dbid")
99
+ end
100
+
101
+ def test_save_and_get_document_content()
102
+ @app.start(:dbfile => @dbfile)
103
+ @app.install_clean()
104
+ doc = QDA::Document.new('About Something')
105
+ str1 = 'fo"o'
106
+ doc.append(str1)
107
+ str2 = "fo'o"
108
+ doc.append(str2)
109
+
110
+ @app.save_document(doc)
111
+ assert(doc.dbid, 'Got a DBID set')
112
+
113
+ fetch_doc = @app.get_doc(doc.dbid)
114
+ assert(fetch_doc, "Got something back")
115
+ assert_equal("fo\"o", fetch_doc[0,4],
116
+ "Got some fragments back")
117
+ assert_equal("fo'o\n", fetch_doc[5,5],
118
+ "Got some fragments back")
119
+
120
+ #assert_equal(2, fetch_doc.fragments.length,
121
+ #"Got some fragments back")
122
+ #assert_equal(str1, fetch_doc.fragments[0].text,
123
+ #"Got single-quote fragment back")
124
+ #assert_equal(str2, fetch_doc.fragments[1].text,
125
+ #"Got double-quote fragment back")
126
+ @app.save_document(doc)
127
+ end
128
+
129
+ def test_save_category_with_code()
130
+ @app.start(:dbfile => @dbfile)
131
+ @app.install_clean()
132
+ cat1 = QDA::Category.new("About 'Something'", nil, 'A memo')
133
+
134
+ doc = QDA::Document.new('Hello')
135
+ doc.append('this')
136
+ doc.append('that')
137
+ @app.save_document(doc)
138
+
139
+ # code 6 characters starting at index 1
140
+ cat1.code(doc.dbid, 1, 6)
141
+
142
+ @app.save_category(cat1)
143
+
144
+ f_cat1 = @app.get_category(cat1.dbid)
145
+ assert_equal(1, f_cat1.num_of_docs,
146
+ 'Have coded 1 doc')
147
+ assert_equal(1, f_cat1.num_of_codes,
148
+ 'Have applied one vector')
149
+ assert_equal(6, f_cat1.num_of_chars,
150
+ 'Have coded 6 characters')
151
+
152
+ texts = @app.get_text_at_category(cat1)
153
+
154
+ assert_equal(1, texts.keys.length,
155
+ 'Have stored one vector')
156
+ assert_equal("his\nth", texts[doc.title][0],
157
+ 'Have retrieved text')
158
+ assert_equal(1, texts[doc.title][0].offset,
159
+ 'Have retrieved text offset')
160
+ assert_equal(6, texts[doc.title][0].length,
161
+ 'Have retrieved text length')
162
+ assert(texts[doc.title][0].docid,
163
+ 'Have retrieved docid')
164
+
165
+
166
+ end
167
+
168
+ def test_basic_save_category
169
+ @app.start(:dbfile => @dbfile)
170
+ @app.install_clean()
171
+ cat1 = QDA::Category.new("About 'Something'", nil, 'the "memo"')
172
+
173
+ @app.save_category(cat1)
174
+ assert(cat1.dbid, 'Category was assigned a database id')
175
+
176
+ f_cat1 = @app.get_category(cat1.dbid)
177
+ assert_equal(cat1.name, f_cat1.name,
178
+ "Name retrieved successfully")
179
+ assert_equal(cat1.memo, f_cat1.memo,
180
+ "Memo retrieved successfully")
181
+
182
+ # test some parent-child stuff
183
+ cat2 = QDA::Category.new('Something "Specific"', cat1)
184
+ @app.save_category(cat2)
185
+ assert(cat2.dbid, 'Category was assigned a database id')
186
+
187
+ cat2a = QDA::Category.new('Something "Specific" & Detailed', cat2)
188
+ @app.save_category(cat2a)
189
+
190
+ cat3 = QDA::Category.new('Something "Else"', cat1)
191
+ @app.save_category(cat3)
192
+
193
+ # @app.dbh.execute("SELECT * FROM category") { | r | p r }
194
+ f_cat2 = @app.get_category(cat2.dbid)
195
+ assert_equal(cat2.name, f_cat2.name,
196
+ "Name retrieved successfully")
197
+
198
+ assert_equal(cat2.dbid, f_cat2.dbid,
199
+ "DBID retrieved successfully")
200
+
201
+ p_cat = @app.get_category(cat2.parent.dbid)
202
+ assert_equal(p_cat.dbid, cat1.dbid,
203
+ "Parent retrieved successfully")
204
+
205
+ assert_nil(@app.get_category_parent(p_cat.dbid),
206
+ "Nil retrieved for root node's parent")
207
+
208
+ roots = @app.get_all_categories()
209
+
210
+ assert_equal(1, roots.length,
211
+ "Root elements retrieved successfully")
212
+ assert_equal("About 'Something'", roots[0].name,
213
+ "Root element retrieved successfully")
214
+ assert_equal(2, roots[0].children.length,
215
+ "Root element children retrieved successfully")
216
+
217
+ cat3 = QDA::Category.new("NEw root node", nil)
218
+ @app.save_category(cat3)
219
+
220
+ roots = @app.get_all_categories()
221
+ assert_equal(2, roots.length,
222
+ "Multiple Root elements retrieved successfully")
223
+
224
+ new_root = @app.get_root_category("NEw root node")
225
+ assert_equal(QDA::Category, new_root.class)
226
+ assert_equal("NEw root node", new_root.name)
227
+ assert_equal(nil, new_root.parent)
228
+ assert_raises(RuntimeError) { @app.get_root_category("Doesn't exist") }
229
+
230
+
231
+ finds = @app.get_categories_by_path('Something')
232
+ assert_equal(3, finds.length, 'Normal name/path search')
233
+
234
+ finds = @app.get_categories_by_path('something')
235
+ assert_equal(3, finds.length, 'Case insensitive name/path search')
236
+
237
+ finds = @app.get_categories_by_path('Something/Something')
238
+ assert_equal(1, finds.length)
239
+
240
+ finds = @app.get_categories_by_path('Fake/Bad')
241
+ assert_equal(0, finds.length)
242
+ end
243
+
244
+ def test_cut_paste_category
245
+ @app.start(:dbfile => @dbfile)
246
+ @app.install_clean()
247
+ cat1 = QDA::Category.new("About 'Something'", nil)
248
+ @app.save_category(cat1)
249
+
250
+ cat2 = QDA::Category.new('Something "Specific"', cat1)
251
+ @app.save_category(cat2)
252
+ cat2a = QDA::Category.new('Something "Specific" & Detailed', cat2)
253
+ @app.save_category(cat2a)
254
+ cat3 = QDA::Category.new('Something "Else"', cat1)
255
+ @app.save_category(cat3)
256
+ cat4 = QDA::Category.new('Something "Again"', cat1)
257
+ @app.save_category(cat4)
258
+
259
+
260
+ cat2.parent = cat3
261
+ @app.save_category(cat2)
262
+
263
+
264
+ cat4.parent = cat3
265
+ @app.save_category(cat4)
266
+
267
+ cat2.parent = cat1
268
+ @app.save_category(cat2)
269
+
270
+ deletions = @app.delete_category(cat3)
271
+ assert_kind_of(Array, deletions)
272
+ assert_equal(2, deletions.length)
273
+ end
274
+
275
+ def test_install()
276
+ @app.start(:dbfile => @dbfile)
277
+ @app.install_clean()
278
+ assert_raises(RuntimeError) { doc = @app.get_doc('foo') }
279
+ end
280
+ end