weft-qda 0.9.6 → 0.9.8
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.
- data/lib/weft.rb +16 -1
- data/lib/weft/WEFT-VERSION-STRING.rb +1 -1
- data/lib/weft/application.rb +17 -74
- data/lib/weft/backend.rb +6 -32
- data/lib/weft/backend/sqlite.rb +222 -164
- data/lib/weft/backend/sqlite/category_tree.rb +52 -48
- data/lib/weft/backend/sqlite/database.rb +57 -0
- data/lib/weft/backend/sqlite/upgradeable.rb +7 -0
- data/lib/weft/broadcaster.rb +90 -0
- data/lib/weft/category.rb +139 -47
- data/lib/weft/codereview.rb +160 -0
- data/lib/weft/coding.rb +74 -23
- data/lib/weft/document.rb +23 -10
- data/lib/weft/exceptions.rb +10 -0
- data/lib/weft/filters.rb +47 -224
- data/lib/weft/filters/indexers.rb +137 -0
- data/lib/weft/filters/input.rb +118 -0
- data/lib/weft/filters/output.rb +101 -0
- data/lib/weft/filters/templates.rb +80 -0
- data/lib/weft/filters/win32backtick.rb +246 -0
- data/lib/weft/query.rb +169 -0
- data/lib/weft/wxgui.rb +349 -294
- data/lib/weft/wxgui/constants.rb +43 -0
- data/lib/weft/wxgui/controls.rb +6 -0
- data/lib/weft/wxgui/controls/category_dropdown.rb +192 -0
- data/lib/weft/wxgui/controls/category_tree.rb +314 -0
- data/lib/weft/wxgui/controls/document_list.rb +97 -0
- data/lib/weft/wxgui/controls/multitype_control.rb +37 -0
- data/lib/weft/wxgui/{inspectors → controls}/textcontrols.rb +235 -64
- data/lib/weft/wxgui/dialogs.rb +144 -41
- data/lib/weft/wxgui/error_handler.rb +116 -36
- data/lib/weft/wxgui/exceptions.rb +7 -0
- data/lib/weft/wxgui/inspectors.rb +61 -208
- data/lib/weft/wxgui/inspectors/category.rb +19 -16
- data/lib/weft/wxgui/inspectors/codereview.rb +90 -132
- data/lib/weft/wxgui/inspectors/document.rb +12 -8
- data/lib/weft/wxgui/inspectors/imagedocument.rb +56 -56
- data/lib/weft/wxgui/inspectors/query.rb +284 -0
- data/lib/weft/wxgui/inspectors/script.rb +147 -23
- data/lib/weft/wxgui/lang/en.rb +69 -0
- data/lib/weft/wxgui/sidebar.rb +90 -432
- data/lib/weft/wxgui/utilities.rb +70 -91
- data/lib/weft/wxgui/workarea.rb +150 -43
- data/share/icons/category.ico +0 -0
- data/share/icons/category.xpm +109 -0
- data/share/icons/codereview.ico +0 -0
- data/share/icons/codereview.xpm +54 -0
- data/share/icons/d_and_c.xpm +126 -0
- data/share/icons/document.ico +0 -0
- data/share/icons/document.xpm +70 -0
- data/share/icons/project.ico +0 -0
- data/share/icons/query.ico +0 -0
- data/share/icons/query.xpm +56 -0
- data/{lib/weft/wxgui → share/icons}/search.xpm +0 -0
- data/share/icons/weft.ico +0 -0
- data/share/icons/weft.xpm +62 -0
- data/share/icons/weft16.ico +0 -0
- data/share/icons/weft32.ico +0 -0
- data/share/templates/category_plain.html +18 -0
- data/share/templates/codereview_plain.html +18 -0
- data/share/templates/document_plain.html +13 -0
- data/share/templates/document_plain.txt +7 -0
- data/test/001-document.rb +55 -36
- data/test/002-category.rb +81 -6
- data/test/003-code.rb +8 -4
- data/test/004-application.rb +13 -34
- data/test/005-query_review.rb +139 -0
- data/test/006-filters.rb +54 -42
- data/test/007-output_filters.rb +113 -0
- data/test/009a-backend_sqlite_basic.rb +95 -24
- data/test/009b-backend_sqlite_complex.rb +43 -62
- data/test/009c_backend_sqlite_bench.rb +5 -10
- data/test/053-doc_inspector.rb +46 -0
- data/test/055-query_window.rb +50 -0
- data/test/all-tests.rb +1 -0
- data/test/test-common.rb +19 -0
- data/test/testdata/empty.qdp +0 -0
- data/test/testdata/simple with space.pdf +0 -0
- data/test/testdata/simple.pdf +0 -0
- data/weft-qda.rb +40 -7
- metadata +74 -14
- data/lib/weft/wxgui/category.xpm +0 -26
- data/lib/weft/wxgui/document.xpm +0 -25
- data/lib/weft/wxgui/inspectors/search.rb +0 -265
- data/lib/weft/wxgui/mondrian.xpm +0 -44
- data/lib/weft/wxgui/weft16.xpm +0 -31
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'test-common'
|
2
|
+
|
3
|
+
require 'weft'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class TestCodeReview < Test::Unit::TestCase
|
7
|
+
include QDA
|
8
|
+
def test_to_query()
|
9
|
+
cr = CodeReview.new()
|
10
|
+
assert_equal(0, cr.number_rows)
|
11
|
+
assert_equal(0, cr.number_cols)
|
12
|
+
|
13
|
+
cat1 = Category.new('foo')
|
14
|
+
cat1.code(1, 10, 40)
|
15
|
+
cat2 = Category.new('bar')
|
16
|
+
cat2.code(1, 70, 20)
|
17
|
+
cat3 = Category.new('baz')
|
18
|
+
cat3.code(1, 40, 40)
|
19
|
+
cat4 = Category.new('qux')
|
20
|
+
cat4.code(1, 100, 15)
|
21
|
+
|
22
|
+
cr.add_col( cat1 )
|
23
|
+
cr.add_col( cat2 )
|
24
|
+
cr.add_row( cat3 )
|
25
|
+
cr.add_row( cat4 )
|
26
|
+
# invalid
|
27
|
+
assert_nil( cr.to_query(nil, 2,2) )
|
28
|
+
# valid
|
29
|
+
assert_kind_of( Query, cr.to_query(nil, 0, 1) )
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_basic
|
33
|
+
cr = CodeReview.new()
|
34
|
+
assert_equal(0, cr.number_rows)
|
35
|
+
assert_equal(0, cr.number_cols)
|
36
|
+
|
37
|
+
cat1 = Category.new('foo')
|
38
|
+
cat1.code(1, 10, 40)
|
39
|
+
cat2 = Category.new('bar')
|
40
|
+
cat2.code(1, 70, 20)
|
41
|
+
cat3 = Category.new('baz')
|
42
|
+
cat3.code(1, 40, 40)
|
43
|
+
cat4 = Category.new('qux')
|
44
|
+
cat4.code(1, 100, 15)
|
45
|
+
|
46
|
+
cr.add_col( cat1 )
|
47
|
+
cr.add_col( cat2 )
|
48
|
+
assert_equal(0, cr.number_rows)
|
49
|
+
assert_equal(2, cr.number_cols)
|
50
|
+
|
51
|
+
cr.add_row( cat3 )
|
52
|
+
cr.add_row( cat4 )
|
53
|
+
assert_equal(2, cr.number_rows)
|
54
|
+
assert_equal(2, cr.number_cols)
|
55
|
+
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# for testing
|
62
|
+
class NullFunction < QDA::Query::Function
|
63
|
+
def initialize(token)
|
64
|
+
@token = token
|
65
|
+
end
|
66
|
+
def calculate()
|
67
|
+
QDA::CodingTable.new()
|
68
|
+
end
|
69
|
+
def to_s()
|
70
|
+
"(NULL-#{@token})"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class TestQuery < Test::Unit::TestCase
|
75
|
+
include QDA
|
76
|
+
|
77
|
+
def test_query
|
78
|
+
q = Query.new( NullFunction.new('FOO') )
|
79
|
+
assert_equal(1, q.num_functions)
|
80
|
+
assert_equal(0, q.num_expressions)
|
81
|
+
assert_equal(QDA::CodingTable.new(), q.calculate)
|
82
|
+
assert_kind_of(NullFunction, q.root)
|
83
|
+
|
84
|
+
q.add_expression( 'AND', NullFunction.new('BAR') )
|
85
|
+
assert_equal(2, q.num_functions)
|
86
|
+
assert_equal(1, q.num_expressions)
|
87
|
+
assert_equal(QDA::CodingTable.new(), q.calculate)
|
88
|
+
assert_kind_of(Query::AND, q.root)
|
89
|
+
|
90
|
+
q.add_expression( 'OR', NullFunction.new('BAZ') )
|
91
|
+
assert_equal(3, q.num_functions)
|
92
|
+
assert_equal(2, q.num_expressions)
|
93
|
+
assert_equal(QDA::CodingTable.new(), q.calculate)
|
94
|
+
assert_kind_of(Query::OR, q.root)
|
95
|
+
# a bad logical operator
|
96
|
+
assert_raises(ArgumentError) do
|
97
|
+
q.add_expression('UG', NullFunction.new('QUX'))
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
def test_or
|
105
|
+
cs_1 = CodingTable.new()
|
106
|
+
cs_2 = CodingTable.new()
|
107
|
+
cs_1.add( Code.new(3, 0, 4) )
|
108
|
+
cs_2.add( Code.new(3, 3, 5) )
|
109
|
+
expr = Query::AND.new(cs_1, cs_2)
|
110
|
+
result = expr.calculate()
|
111
|
+
assert_equal(1, result.num_of_docs)
|
112
|
+
assert_equal(1, result.num_of_chars)
|
113
|
+
assert_equal(1, result.num_of_passages)
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_and_not
|
117
|
+
cs_1 = CodingTable.new()
|
118
|
+
cs_2 = CodingTable.new()
|
119
|
+
cs_1.add( Code.new(3, 0, 4) )
|
120
|
+
cs_2.add( Code.new(3, 3, 5) )
|
121
|
+
expr = Query::AND_NOT.new(cs_1, cs_2)
|
122
|
+
result = expr.calculate()
|
123
|
+
assert_equal(1, result.num_of_docs)
|
124
|
+
assert_equal(3, result.num_of_chars)
|
125
|
+
assert_equal(1, result.num_of_passages)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_or
|
129
|
+
cs_1 = CodingTable.new()
|
130
|
+
cs_2 = CodingTable.new()
|
131
|
+
cs_1.add( Code.new(3, 0, 4) )
|
132
|
+
cs_2.add( Code.new(3, 3, 5) )
|
133
|
+
expr = Query::OR.new(cs_1, cs_2)
|
134
|
+
result = expr.calculate()
|
135
|
+
assert_equal(1, result.num_of_docs)
|
136
|
+
assert_equal(8, result.num_of_chars)
|
137
|
+
assert_equal(1, result.num_of_passages)
|
138
|
+
end
|
139
|
+
end
|
data/test/006-filters.rb
CHANGED
@@ -1,31 +1,33 @@
|
|
1
|
-
require '
|
1
|
+
require 'test-common'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'weft/application'
|
6
|
-
require 'weft/backend'
|
7
|
-
require 'weft/document'
|
8
|
-
require 'weft/filters'
|
3
|
+
require 'weft'
|
9
4
|
|
10
5
|
require 'test/unit'
|
11
6
|
|
12
7
|
class TestFilter < Test::Unit::TestCase
|
13
|
-
|
14
|
-
|
8
|
+
include QDA
|
9
|
+
def test_filter_types()
|
10
|
+
import_filters = Filters::import_filters
|
11
|
+
assert_kind_of(Hash, import_filters)
|
12
|
+
assert_kind_of(Array, import_filters[QDA::Document])
|
13
|
+
assert(import_filters[Document].length > 0)
|
14
|
+
|
15
|
+
export_filters = Filters::export_filters
|
16
|
+
assert_kind_of(Hash, export_filters)
|
17
|
+
assert_kind_of(Array, export_filters[Document])
|
15
18
|
end
|
16
|
-
|
19
|
+
|
17
20
|
def test_unix_utf8()
|
18
|
-
|
19
|
-
doc =
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
textfile = sample_file('text1-unix-utf8.txt')
|
22
|
+
doc = Filters.import_file(Document, textfile) do | doc, filter |
|
23
|
+
str = "This is a text document\nin unix unicode.\n"
|
24
|
+
assert_equal(str, doc.text, "Document text read in")
|
25
|
+
doc.title = 'utf-8'
|
26
|
+
end
|
27
|
+
assert_equal('utf-8', doc.title)
|
23
28
|
end
|
24
29
|
|
25
30
|
def test_indexer
|
26
|
-
idx = QDA::Indexer.new()
|
27
|
-
idx.index('foo')
|
28
|
-
|
29
31
|
widx = QDA::WordIndexer.new()
|
30
32
|
my_word = 'SOMETHING'
|
31
33
|
widx.index(my_word)
|
@@ -34,34 +36,33 @@ class TestFilter < Test::Unit::TestCase
|
|
34
36
|
end
|
35
37
|
|
36
38
|
def test_dos_ascii()
|
37
|
-
|
38
|
-
|
39
|
+
text_filter = QDA::Filters.find_import_filter(QDA::Document, 'txt')
|
40
|
+
filter = text_filter.new()
|
41
|
+
doc = filter.run(sample_file('text1-dos-ascii.txt'))
|
39
42
|
|
40
43
|
str = "This is a text document\nin dos ascii.\n"
|
41
44
|
assert_equal(str, doc.text, "Document text read in")
|
42
45
|
end
|
43
46
|
|
44
47
|
def test_pdf
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
doc
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
assert_equal( word, doc[offset, word.length] )
|
55
|
-
end
|
56
|
-
end
|
48
|
+
doc = Filters.import_file(Document, sample_file('simple.pdf') )
|
49
|
+
txt = "This is a simple unlocked PDF document. " <<
|
50
|
+
"It should import without problem into Weft QDA.\n\n"
|
51
|
+
assert_equal(txt, doc.text)
|
52
|
+
|
53
|
+
doc = Filters.import_file(Document, sample_file('simple with space.pdf') )
|
54
|
+
txt = "This is a simple unlocked PDF document. " <<
|
55
|
+
"It should import without problem into Weft QDA.\n\n"
|
56
|
+
assert_equal(txt, doc.text, 'OK importing file with space in name')
|
57
57
|
end
|
58
58
|
|
59
59
|
def test_word_indexing()
|
60
|
-
|
60
|
+
text_filter = Filters.find_import_filter(Document, 'txt')
|
61
|
+
filter = text_filter.new()
|
62
|
+
|
61
63
|
windxr = QDA::WordIndexer.new()
|
62
64
|
filter.add_indexer(windxr)
|
63
|
-
doc = filter.
|
64
|
-
'word_indexing')
|
65
|
+
doc = filter.run( sample_file('autocoding-test.txt') )
|
65
66
|
# ordinary, capitalised, short, apostrophe, longer
|
66
67
|
test_words = [ 'the', 'Before', 'I', 'It\'s', 'opinions' ]
|
67
68
|
test_words.each do | test_word |
|
@@ -71,25 +72,36 @@ class TestFilter < Test::Unit::TestCase
|
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
|
-
def test_indexing_iso_8859_1
|
75
|
-
|
76
|
-
|
75
|
+
def test_indexing_iso_8859_1()
|
76
|
+
text_filter = Filters.find_import_filter(Document, 'txt')
|
77
|
+
filter = text_filter.new()
|
78
|
+
|
79
|
+
windxr = WordIndexer.new()
|
77
80
|
filter.add_indexer(windxr)
|
78
|
-
|
81
|
+
|
82
|
+
doc = filter.run( sample_file('iso-8859-1.txt') )
|
79
83
|
word_rx = /[\w\xC0-\xD6\xD8-\xF6\xF8-\xFF][\w\xC0-\xD6\xD8-\xF6\xF8-\xFF\']+/
|
80
84
|
windxr.words.each_key do | word |
|
81
85
|
assert_match(word_rx, word)
|
82
86
|
end
|
87
|
+
|
88
|
+
windxr2 = WordIndexer.new()
|
89
|
+
windxr2.feed(doc)
|
90
|
+
windxr.words.each do | word, offsets|
|
91
|
+
assert_equal(offsets, windxr2.words[word])
|
92
|
+
end
|
93
|
+
|
83
94
|
end
|
84
95
|
|
85
96
|
def test_autocoding
|
86
|
-
|
97
|
+
text_filter = QDA::Filters.find_import_filter(QDA::Document, 'txt')
|
98
|
+
filter = text_filter.new()
|
99
|
+
|
87
100
|
autocoder = QDA::AutoCoder.new(/^\*\*(.*)\*\*\s*$/ => 'Heading',
|
88
101
|
/^(.*)\:\s*$/ => 'Speaker')
|
89
102
|
filter.add_indexer(autocoder)
|
90
103
|
|
91
|
-
doc = filter.
|
92
|
-
'autocoding')
|
104
|
+
doc = filter.run( sample_file('autocoding-test.txt') )
|
93
105
|
|
94
106
|
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
107
|
assert_equal(str, doc.text)
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test-common'
|
2
|
+
|
3
|
+
require 'weft'
|
4
|
+
require 'tempfile' # so we can test output
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
class TestFilter < Test::Unit::TestCase
|
9
|
+
include QDA
|
10
|
+
|
11
|
+
def run_filter(obj, filter)
|
12
|
+
tmp = Tempfile.new('output')
|
13
|
+
filter.write(obj, tmp)
|
14
|
+
tmp.rewind()
|
15
|
+
tmp.read()
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_filter_types()
|
19
|
+
import_filters = Filters::import_filters
|
20
|
+
assert_kind_of(Hash, import_filters)
|
21
|
+
assert_kind_of(Array, import_filters[QDA::Document])
|
22
|
+
assert(import_filters[Document].length > 0)
|
23
|
+
|
24
|
+
export_filters = Filters::export_filters
|
25
|
+
assert_kind_of(Hash, export_filters)
|
26
|
+
assert_kind_of(Array, export_filters[Category])
|
27
|
+
assert(export_filters[Category].length > 0)
|
28
|
+
assert(export_filters[Document].length > 0)
|
29
|
+
assert(export_filters[CodeReview].length > 0)
|
30
|
+
|
31
|
+
assert( Filters.can_export?(Category) )
|
32
|
+
assert( Filters.can_export?(Document) )
|
33
|
+
assert( Filters.can_export?(CodeReview) )
|
34
|
+
assert( ! Filters.can_export?(Query) )
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_export_document()
|
39
|
+
doc = Document.new('foo')
|
40
|
+
doc.append('blah blah blah')
|
41
|
+
filter = Filters::DocumentTextOutput.new()
|
42
|
+
|
43
|
+
tmp = Tempfile.new('doc_text')
|
44
|
+
filter.write(doc, tmp)
|
45
|
+
tmp.rewind()
|
46
|
+
contents = tmp.read()
|
47
|
+
# Proper template not written yet
|
48
|
+
# assert_match(/blah/m, contents, 'Looks a bit like the document')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_export_category()
|
52
|
+
@app = QDA::Application.new()
|
53
|
+
@app.extend(QDA::Backend::SQLite)
|
54
|
+
@app.start(:memory => true)
|
55
|
+
@app.install_clean()
|
56
|
+
|
57
|
+
doc = Document.new('My Document')
|
58
|
+
doc.append('This is some text in the document')
|
59
|
+
@app.save_doc(doc)
|
60
|
+
|
61
|
+
cat = Category.new('foo & bar')
|
62
|
+
cat.code(doc.dbid, 13, 7)
|
63
|
+
@app.save_category(cat)
|
64
|
+
|
65
|
+
contents = run_filter( cat, Filters::CategoryHTMLOutput.new(@app) )
|
66
|
+
assert_match(/<html>.*<\/html>/m, contents, "Sort of looks like HTML")
|
67
|
+
assert_match(/foo & bar/, contents, "Title's mentioned somewhere")
|
68
|
+
assert_match(/foo/, contents, "Category name's mentioned somewhere")
|
69
|
+
assert_match(/text in/, contents, "Document text is included")
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_export_codereview_csv()
|
73
|
+
@app = QDA::Application.new()
|
74
|
+
@app.extend(QDA::Backend::SQLite)
|
75
|
+
@app.start(:memory => true)
|
76
|
+
@app.install_clean()
|
77
|
+
cr = mock_codereview()
|
78
|
+
tmp = Tempfile.new('codereview_csv')
|
79
|
+
|
80
|
+
filter = Filters::CodeReviewCSVOutput.new(@app)
|
81
|
+
filter.write(cr, tmp)
|
82
|
+
tmp.rewind()
|
83
|
+
lines = tmp.read().split("\n")
|
84
|
+
assert_match(/foo,bar/, lines[0])
|
85
|
+
assert_equal('baz,10,10', lines[1])
|
86
|
+
end
|
87
|
+
|
88
|
+
def mock_codereview()
|
89
|
+
cr = CodeReview.new()
|
90
|
+
cr.count_method = :num_of_chars
|
91
|
+
cat1 = Category.new('foo')
|
92
|
+
cat1.code(1, 10, 40)
|
93
|
+
cat2 = Category.new('bar')
|
94
|
+
cat2.code(1, 70, 20)
|
95
|
+
cat3 = Category.new('baz')
|
96
|
+
cat3.code(1, 40, 40)
|
97
|
+
cat4 = Category.new('qux')
|
98
|
+
cat4.code(1, 85, 15)
|
99
|
+
|
100
|
+
cr.add_col( cat1 )
|
101
|
+
cr.add_col( cat2 )
|
102
|
+
|
103
|
+
cr.add_row( cat3 )
|
104
|
+
cr.add_row( cat4 )
|
105
|
+
cr
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_export_codereview_html
|
109
|
+
cr = mock_codereview()
|
110
|
+
contents = run_filter(cr, Filters::CodeReviewHTMLOutput.new() )
|
111
|
+
assert_match(/<table/, contents, "There's a table in there somewhere")
|
112
|
+
end
|
113
|
+
end
|
@@ -1,8 +1,23 @@
|
|
1
|
-
require '
|
2
|
-
$:.push('../lib/')
|
3
|
-
|
1
|
+
require 'test-common'
|
4
2
|
require 'weft'
|
5
|
-
|
3
|
+
|
4
|
+
class DummyClient
|
5
|
+
attr_reader :event_log
|
6
|
+
include QDA::Subscriber
|
7
|
+
|
8
|
+
def initialize(app = nil)
|
9
|
+
@event_log = []
|
10
|
+
subscribe(app, :all)
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset_log()
|
14
|
+
@event_log = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def notify(evt, data)
|
18
|
+
event_log.push( :evt => evt, :data => data )
|
19
|
+
end
|
20
|
+
end
|
6
21
|
|
7
22
|
class TestSQLiteBasic < Test::Unit::TestCase
|
8
23
|
def sample_file(filename)
|
@@ -13,17 +28,15 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
13
28
|
@dbfile = nil
|
14
29
|
@app = QDA::Application.new()
|
15
30
|
@app.extend(QDA::Backend::SQLite)
|
31
|
+
@client = DummyClient.new(@app)
|
16
32
|
end
|
17
33
|
|
18
34
|
# delete any files hanging around
|
19
35
|
def teardown()
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
File.delete(@app.dbfile)
|
25
|
-
end
|
26
|
-
end
|
36
|
+
@app.end
|
37
|
+
if @app.dbfile and File.exist?(@app.dbfile)
|
38
|
+
File.delete(@app.dbfile)
|
39
|
+
end
|
27
40
|
end
|
28
41
|
|
29
42
|
# test save & revert
|
@@ -33,7 +46,7 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
33
46
|
doc = QDA::Document.new('Doc-1')
|
34
47
|
@app.save_document(doc)
|
35
48
|
|
36
|
-
assert_raises(
|
49
|
+
assert_raises(QDA::Backend::BackendError, "Cannot save without filename") do
|
37
50
|
doc = @app.save()
|
38
51
|
end
|
39
52
|
|
@@ -78,9 +91,14 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
78
91
|
@app.install_clean()
|
79
92
|
doc = QDA::Document.new('About Something')
|
80
93
|
assert_nil(doc.dbid, "No DBID set")
|
94
|
+
assert_nil( @app.doc_exists(doc.title) )
|
95
|
+
|
96
|
+
# test saving
|
81
97
|
@app.save_document(doc)
|
82
98
|
assert(doc.dbid, 'Got a DBID set')
|
83
|
-
|
99
|
+
assert_equal( doc.dbid, @app.doc_exists(doc.title) )
|
100
|
+
|
101
|
+
# test fetching by document identifier
|
84
102
|
fetch_doc = @app.get_doc(doc.dbid)
|
85
103
|
assert(fetch_doc, "Got something back")
|
86
104
|
|
@@ -89,6 +107,7 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
89
107
|
assert_equal(doc.title, fetch_doc.title,
|
90
108
|
"Fetched back thing has the same dbid")
|
91
109
|
|
110
|
+
# test fetching by document title
|
92
111
|
fetch_doc = @app.get_doc(doc.title)
|
93
112
|
assert(fetch_doc, "Got something back")
|
94
113
|
|
@@ -96,8 +115,25 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
96
115
|
"Fetched back thing has the same dbid")
|
97
116
|
assert_equal(doc.title, fetch_doc.title,
|
98
117
|
"Fetched back thing has the same dbid")
|
99
|
-
end
|
100
118
|
|
119
|
+
end
|
120
|
+
def test_magic_renaming_document()
|
121
|
+
@app.start(:dbfile => @dbfile)
|
122
|
+
@app.install_clean()
|
123
|
+
|
124
|
+
@app.save_document(QDA::Document.new('Foo'))
|
125
|
+
doc = QDA::Document.new('Foo')
|
126
|
+
assert_raises(QDA::NotUniqueNameError) { @app.save_doc(doc) }
|
127
|
+
# test duplicate magic renaming
|
128
|
+
@app.save_document(doc, true)
|
129
|
+
assert(doc.dbid)
|
130
|
+
assert_equal('Foo (1)', doc.title)
|
131
|
+
doc_1 = QDA::Document.new('Foo')
|
132
|
+
@app.save_document(doc_1, true)
|
133
|
+
assert(doc_1.dbid)
|
134
|
+
assert_equal('Foo (2)', doc_1.title)
|
135
|
+
end
|
136
|
+
|
101
137
|
def test_save_and_get_document_content()
|
102
138
|
@app.start(:dbfile => @dbfile)
|
103
139
|
@app.install_clean()
|
@@ -165,6 +201,24 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
165
201
|
|
166
202
|
end
|
167
203
|
|
204
|
+
|
205
|
+
def test_root_category()
|
206
|
+
@app.start(:dbfile => @dbfile)
|
207
|
+
@app.install_clean()
|
208
|
+
root = QDA::Category.new("ROOT", nil, 'the "memo"')
|
209
|
+
@app.save_category(root)
|
210
|
+
f_root = @app.get_root_category('ROOT')
|
211
|
+
assert_equal(nil, f_root.parent)
|
212
|
+
assert_equal('ROOT', f_root.name)
|
213
|
+
f_root.name = 'RENAMED'
|
214
|
+
@app.save_category(f_root)
|
215
|
+
|
216
|
+
assert_raises(QDA::NotFoundError) { @app.get_root_category('ROOT') }
|
217
|
+
f_root = @app.get_root_category('RENAMED')
|
218
|
+
assert_equal(nil, f_root.parent)
|
219
|
+
assert_equal('RENAMED', f_root.name)
|
220
|
+
end
|
221
|
+
|
168
222
|
def test_basic_save_category
|
169
223
|
@app.start(:dbfile => @dbfile)
|
170
224
|
@app.install_clean()
|
@@ -178,19 +232,29 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
178
232
|
"Name retrieved successfully")
|
179
233
|
assert_equal(cat1.memo, f_cat1.memo,
|
180
234
|
"Memo retrieved successfully")
|
181
|
-
|
235
|
+
|
236
|
+
f_cat1 = @app.get_category("/About 'Something'")
|
237
|
+
assert_equal(cat1, f_cat1)
|
238
|
+
|
182
239
|
# test some parent-child stuff
|
183
240
|
cat2 = QDA::Category.new('Something "Specific"', cat1)
|
184
241
|
@app.save_category(cat2)
|
185
242
|
assert(cat2.dbid, 'Category was assigned a database id')
|
243
|
+
assert_equal(cat1, cat2.parent)
|
244
|
+
|
245
|
+
f_cat1 = @app.get_category(cat1.dbid, true)
|
246
|
+
assert_equal(1, f_cat1.children.length)
|
186
247
|
|
248
|
+
f_cat2 = @app.get_category("/About 'Something'/Something")
|
249
|
+
assert_equal(cat2, f_cat2)
|
250
|
+
|
251
|
+
|
187
252
|
cat2a = QDA::Category.new('Something "Specific" & Detailed', cat2)
|
188
253
|
@app.save_category(cat2a)
|
189
254
|
|
190
255
|
cat3 = QDA::Category.new('Something "Else"', cat1)
|
191
256
|
@app.save_category(cat3)
|
192
257
|
|
193
|
-
# @app.dbh.execute("SELECT * FROM category") { | r | p r }
|
194
258
|
f_cat2 = @app.get_category(cat2.dbid)
|
195
259
|
assert_equal(cat2.name, f_cat2.name,
|
196
260
|
"Name retrieved successfully")
|
@@ -225,8 +289,7 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
225
289
|
assert_equal(QDA::Category, new_root.class)
|
226
290
|
assert_equal("NEw root node", new_root.name)
|
227
291
|
assert_equal(nil, new_root.parent)
|
228
|
-
assert_raises(
|
229
|
-
|
292
|
+
assert_raises(QDA::NotFoundError) { @app.get_root_category("Doesn't exist") }
|
230
293
|
|
231
294
|
finds = @app.get_categories_by_path('Something')
|
232
295
|
assert_equal(3, finds.length, 'Normal name/path search')
|
@@ -244,7 +307,7 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
244
307
|
def test_cut_paste_category
|
245
308
|
@app.start(:dbfile => @dbfile)
|
246
309
|
@app.install_clean()
|
247
|
-
cat1 = QDA::Category.new("
|
310
|
+
cat1 = QDA::Category.new("Root", nil)
|
248
311
|
@app.save_category(cat1)
|
249
312
|
|
250
313
|
cat2 = QDA::Category.new('Something "Specific"', cat1)
|
@@ -256,20 +319,28 @@ class TestSQLiteBasic < Test::Unit::TestCase
|
|
256
319
|
cat4 = QDA::Category.new('Something "Again"', cat1)
|
257
320
|
@app.save_category(cat4)
|
258
321
|
|
259
|
-
|
260
322
|
cat2.parent = cat3
|
261
323
|
@app.save_category(cat2)
|
324
|
+
assert_equal("/Root/Something \"Else\"/Something \"Specific\"",
|
325
|
+
cat2.path)
|
262
326
|
|
263
|
-
|
264
327
|
cat4.parent = cat3
|
265
328
|
@app.save_category(cat4)
|
329
|
+
|
266
330
|
|
331
|
+
cat4_x = @app.get_category(cat4.dbid)
|
332
|
+
assert_equal(cat3, cat4_x.parent)
|
333
|
+
|
267
334
|
cat2.parent = cat1
|
268
335
|
@app.save_category(cat2)
|
269
336
|
|
270
|
-
|
271
|
-
|
272
|
-
|
337
|
+
@client.reset_log
|
338
|
+
deletion = @app.delete_category(cat3)
|
339
|
+
assert_kind_of(QDA::Category, deletion)
|
340
|
+
assert_equal(cat3, deletion)
|
341
|
+
assert_raises(QDA::NotFoundError) { @app.get_category(cat4.dbid) }
|
342
|
+
assert_raises(QDA::NotFoundError) { @app.get_category(cat3.dbid) }
|
343
|
+
assert_equal(2, @client.event_log.length)
|
273
344
|
end
|
274
345
|
|
275
346
|
def test_install()
|