simply_stored 0.1.4

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.
Files changed (121) hide show
  1. data/lib/simply_stored/class_methods_base.rb +31 -0
  2. data/lib/simply_stored/couch/belongs_to.rb +117 -0
  3. data/lib/simply_stored/couch/ext/couch_potato.rb +16 -0
  4. data/lib/simply_stored/couch/has_many.rb +148 -0
  5. data/lib/simply_stored/couch/has_one.rb +93 -0
  6. data/lib/simply_stored/couch/validations.rb +74 -0
  7. data/lib/simply_stored/couch/views/array_property_view_spec.rb +22 -0
  8. data/lib/simply_stored/couch/views.rb +1 -0
  9. data/lib/simply_stored/couch.rb +278 -0
  10. data/lib/simply_stored/instance_methods.rb +143 -0
  11. data/lib/simply_stored/simpledb/associations.rb +196 -0
  12. data/lib/simply_stored/simpledb/attributes.rb +173 -0
  13. data/lib/simply_stored/simpledb/storag.rb +85 -0
  14. data/lib/simply_stored/simpledb/validations.rb +88 -0
  15. data/lib/simply_stored/simpledb.rb +212 -0
  16. data/lib/simply_stored/storage.rb +93 -0
  17. data/lib/simply_stored.rb +9 -0
  18. data/test/custom_views_test.rb +33 -0
  19. data/test/fixtures/couch.rb +182 -0
  20. data/test/fixtures/simpledb/item.rb +11 -0
  21. data/test/fixtures/simpledb/item_daddy.rb +8 -0
  22. data/test/fixtures/simpledb/log_item.rb +3 -0
  23. data/test/fixtures/simpledb/namespace_bar.rb +5 -0
  24. data/test/fixtures/simpledb/namespace_foo.rb +7 -0
  25. data/test/fixtures/simpledb/protected_item.rb +3 -0
  26. data/test/simply_stored_couch_test.rb +1684 -0
  27. data/test/simply_stored_simpledb_test.rb +1341 -0
  28. data/test/test_helper.rb +22 -0
  29. data/test/vendor/dhaka-2.2.1/lib/dhaka/dot/dot.rb +29 -0
  30. data/test/vendor/dhaka-2.2.1/lib/dhaka/evaluator/evaluator.rb +133 -0
  31. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/closure_hash.rb +15 -0
  32. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar.rb +240 -0
  33. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar_symbol.rb +27 -0
  34. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/precedence.rb +19 -0
  35. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/production.rb +36 -0
  36. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/accept_actions.rb +36 -0
  37. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/alphabet.rb +21 -0
  38. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/compiled_lexer.rb +46 -0
  39. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/dfa.rb +121 -0
  40. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexeme.rb +32 -0
  41. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer.rb +70 -0
  42. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer_run.rb +78 -0
  43. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_grammar.rb +392 -0
  44. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_parser.rb +2010 -0
  45. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_tokenizer.rb +14 -0
  46. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/specification.rb +96 -0
  47. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state.rb +68 -0
  48. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state_machine.rb +37 -0
  49. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/action.rb +55 -0
  50. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/channel.rb +58 -0
  51. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/compiled_parser.rb +51 -0
  52. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/conflict.rb +54 -0
  53. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/item.rb +42 -0
  54. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_result.rb +50 -0
  55. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_tree.rb +66 -0
  56. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser.rb +165 -0
  57. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_methods.rb +11 -0
  58. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_run.rb +39 -0
  59. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_state.rb +74 -0
  60. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/token.rb +22 -0
  61. data/test/vendor/dhaka-2.2.1/lib/dhaka/runtime.rb +51 -0
  62. data/test/vendor/dhaka-2.2.1/lib/dhaka/tokenizer/tokenizer.rb +190 -0
  63. data/test/vendor/dhaka-2.2.1/lib/dhaka.rb +62 -0
  64. data/test/vendor/dhaka-2.2.1/test/all_tests.rb +5 -0
  65. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator.rb +64 -0
  66. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator_test.rb +43 -0
  67. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar.rb +41 -0
  68. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar_test.rb +9 -0
  69. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_test_methods.rb +9 -0
  70. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer.rb +39 -0
  71. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer_test.rb +38 -0
  72. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_evaluator.rb +43 -0
  73. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar.rb +24 -0
  74. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar_test.rb +30 -0
  75. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_lexer_specification.rb +23 -0
  76. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_parser_test.rb +33 -0
  77. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_grammar.rb +23 -0
  78. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_tokenizer.rb +22 -0
  79. data/test/vendor/dhaka-2.2.1/test/brackets/brackets_test.rb +28 -0
  80. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver.rb +46 -0
  81. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver_test.rb +276 -0
  82. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator.rb +284 -0
  83. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator_test.rb +38 -0
  84. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_grammar.rb +104 -0
  85. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer.rb +109 -0
  86. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_specification.rb +37 -0
  87. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_test.rb +58 -0
  88. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser.rb +879 -0
  89. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser_test.rb +55 -0
  90. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_test.rb +170 -0
  91. data/test/vendor/dhaka-2.2.1/test/core/another_lalr_but_not_slr_grammar.rb +20 -0
  92. data/test/vendor/dhaka-2.2.1/test/core/compiled_parser_test.rb +44 -0
  93. data/test/vendor/dhaka-2.2.1/test/core/dfa_test.rb +170 -0
  94. data/test/vendor/dhaka-2.2.1/test/core/evaluator_test.rb +22 -0
  95. data/test/vendor/dhaka-2.2.1/test/core/grammar_test.rb +83 -0
  96. data/test/vendor/dhaka-2.2.1/test/core/lalr_but_not_slr_grammar.rb +19 -0
  97. data/test/vendor/dhaka-2.2.1/test/core/lexer_test.rb +139 -0
  98. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar.rb +7 -0
  99. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar_test.rb +8 -0
  100. data/test/vendor/dhaka-2.2.1/test/core/nullable_grammar.rb +21 -0
  101. data/test/vendor/dhaka-2.2.1/test/core/parse_result_test.rb +44 -0
  102. data/test/vendor/dhaka-2.2.1/test/core/parser_state_test.rb +24 -0
  103. data/test/vendor/dhaka-2.2.1/test/core/parser_test.rb +131 -0
  104. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar.rb +17 -0
  105. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar_test.rb +9 -0
  106. data/test/vendor/dhaka-2.2.1/test/core/rr_conflict_grammar.rb +21 -0
  107. data/test/vendor/dhaka-2.2.1/test/core/simple_grammar.rb +22 -0
  108. data/test/vendor/dhaka-2.2.1/test/core/sr_conflict_grammar.rb +16 -0
  109. data/test/vendor/dhaka-2.2.1/test/dhaka_test_helper.rb +17 -0
  110. data/test/vendor/dhaka-2.2.1/test/fake_logger.rb +17 -0
  111. data/test/vendor/simplerdb-0.2/lib/simplerdb/client_exception.rb +10 -0
  112. data/test/vendor/simplerdb-0.2/lib/simplerdb/db.rb +146 -0
  113. data/test/vendor/simplerdb-0.2/lib/simplerdb/query_language.rb +266 -0
  114. data/test/vendor/simplerdb-0.2/lib/simplerdb/server.rb +33 -0
  115. data/test/vendor/simplerdb-0.2/lib/simplerdb/servlet.rb +191 -0
  116. data/test/vendor/simplerdb-0.2/lib/simplerdb.rb +3 -0
  117. data/test/vendor/simplerdb-0.2/test/functional_test.rb +81 -0
  118. data/test/vendor/simplerdb-0.2/test/query_evaluator_test.rb +73 -0
  119. data/test/vendor/simplerdb-0.2/test/query_parser_test.rb +64 -0
  120. data/test/vendor/simplerdb-0.2/test/simplerdb_test.rb +80 -0
  121. metadata +182 -0
@@ -0,0 +1,139 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+
3
+ class TestLexer < Test::Unit::TestCase
4
+ class LexerSpec < Dhaka::LexerSpecification
5
+
6
+ for_pattern 'zz' do
7
+ "two zs"
8
+ end
9
+
10
+ for_pattern '\w(\w|\d)*' do
11
+ "word #{current_lexeme.value}"
12
+ end
13
+
14
+ # can optionally use Regexps as well
15
+ for_pattern(/(\d)*(\.\d+)?/) do
16
+ "number #{current_lexeme.value}"
17
+ end
18
+
19
+ for_pattern '<.*>' do
20
+ "tag #{current_lexeme.value}"
21
+ end
22
+
23
+ for_pattern ' +' do
24
+ #ignores whitespace
25
+ end
26
+
27
+ for_pattern "\n+" do
28
+ "newline"
29
+ end
30
+
31
+ for_pattern "\r+" do
32
+ "carriage return"
33
+ end
34
+
35
+ end
36
+
37
+ def test_lexer_with_valid_input
38
+ lexer = Dhaka::Lexer.new(LexerSpec)
39
+ eval(lexer.compile_to_ruby_source_as(:SomeLexer))
40
+ input = "these are words a z zz caPITALIZED word \r
41
+ this is a float 12.00 an integer 134 a float without a leading digit .2335 another word1"
42
+ results = SomeLexer.lex(input).collect
43
+ assert_equal(
44
+ ["word these",
45
+ "word are",
46
+ "word words",
47
+ "word a",
48
+ "word z",
49
+ "two zs",
50
+ "word caPITALIZED",
51
+ "word word",
52
+ "carriage return",
53
+ "newline",
54
+ "word this",
55
+ "word is",
56
+ "word a",
57
+ "word float",
58
+ "number 12.00",
59
+ "word an",
60
+ "word integer",
61
+ "number 134",
62
+ "word a",
63
+ "word float",
64
+ "word without",
65
+ "word a",
66
+ "word leading",
67
+ "word digit",
68
+ "number .2335",
69
+ "word another",
70
+ "word word1"], results[0..-2])
71
+ end
72
+
73
+ def test_lexer_with_invalid_input
74
+ lexer = Dhaka::Lexer.new(LexerSpec)
75
+ result = lexer.lex("this will cause an error here 123.").each do |result|
76
+ end
77
+ assert(result.has_error?)
78
+ assert_equal(34, result.unexpected_char_index)
79
+ end
80
+
81
+ def test_lexer_with_greedy_character_consumption
82
+ lexer = Dhaka::Lexer.new(LexerSpec)
83
+ results = lexer.lex("<html></html>this is a word").collect
84
+ assert_equal(["tag <html></html>",
85
+ "word this",
86
+ "word is",
87
+ "word a",
88
+ "word word"], results[0..-2])
89
+ end
90
+
91
+ class LexerWithLookaheadsSpec < Dhaka::LexerSpecification
92
+
93
+ for_pattern '\s+' do
94
+ # ignore whitespace
95
+ end
96
+
97
+ for_pattern ':/\w+' do
98
+ "a symbol qualifier"
99
+ end
100
+
101
+ for_pattern(":/[^a-zA-Z \n\r\t]*") do
102
+ "a colon"
103
+ end
104
+
105
+ for_pattern "ab/cd" do
106
+ "ab followed by cd: #{current_lexeme.value}"
107
+ end
108
+
109
+ for_pattern "abc/e" do
110
+ "abc followed by e: #{current_lexeme.value}"
111
+ end
112
+
113
+ for_pattern '\w+' do
114
+ "word #{current_lexeme.value}"
115
+ end
116
+
117
+ for_pattern '\d+' do
118
+ "number #{current_lexeme.value}"
119
+ end
120
+
121
+ end
122
+
123
+ def test_lexer_with_regexes_that_use_lookaheads
124
+ lexer = Dhaka::Lexer.new(LexerWithLookaheadsSpec)
125
+ eval(lexer.compile_to_ruby_source_as(:LexerWithTrickyLookaheads))
126
+ results = LexerWithTrickyLookaheads.lex("234 : :whatever :1934 abcd ::").collect
127
+ assert_equal(["number 234",
128
+ "a colon",
129
+ "a symbol qualifier",
130
+ "word whatever",
131
+ "a colon",
132
+ "number 1934",
133
+ "ab followed by cd: ab",
134
+ "word cd",
135
+ "a colon",
136
+ "a colon"], results[0..-2])
137
+ end
138
+
139
+ end
@@ -0,0 +1,7 @@
1
+ class MalformedGrammar < Dhaka::Grammar
2
+
3
+ for_symbol('foo') do
4
+ bar %w| baz |
5
+ end
6
+
7
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + "/malformed_grammar"
3
+
4
+ class TestMalformedGrammar < Test::Unit::TestCase
5
+ def test_must_have_a_start_symbol_in_order_to_generate_a_parser
6
+ assert_raises(Dhaka::NoStartProductionsError) {Dhaka::Parser.new(MalformedGrammar)}
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ class NullableGrammar < Dhaka::Grammar
2
+
3
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
4
+ tuple %w| Tuple |
5
+ end
6
+
7
+ for_symbol('Tuple') do
8
+ element_list %w| ( Elements ) |
9
+ end
10
+
11
+ for_symbol('Elements') do
12
+ empty_element_list %w| |
13
+ concatenate_element_lists %w| Character Elements |
14
+ end
15
+
16
+ for_symbol('Character') do
17
+ literal_a %w| a |
18
+ literal_b %w| b |
19
+ end
20
+
21
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + '/simple_grammar'
3
+
4
+ class TestParseSuccessResult < Test::Unit::TestCase
5
+ include Dhaka
6
+
7
+ def composite_node(production, child_nodes, dot_name)
8
+ node = ParseTreeCompositeNode.new(SimpleGrammar.production_named(production))
9
+ node.child_nodes.concat child_nodes
10
+ node.stubs(:object_id).returns(dot_name)
11
+ node
12
+ end
13
+
14
+ def leaf_node(token, value, dot_name)
15
+ node = ParseTreeLeafNode.new(Token.new(token, value, nil))
16
+ node.stubs(:object_id).returns(dot_name)
17
+ node
18
+ end
19
+
20
+ def test_parse_tree_can_be_exported_to_dot_format
21
+ first_term = composite_node('literal', [leaf_node('n', 1, "literal_1")], "first_term")
22
+ second_term = composite_node('literal', [leaf_node('n', 2, "literal_2")], "second_term")
23
+ addition_term = leaf_node('-', nil, "subtraction_operator")
24
+ tree = composite_node('subtraction', [first_term, addition_term, second_term], "expression")
25
+ result = ParseSuccessResult.new(tree)
26
+ assert_equal(
27
+ %(digraph x {
28
+ node [fontsize="10" shape="box" size="5"]
29
+ expression [label="subtraction E ::= E - T"]
30
+ expression -> first_term
31
+ first_term [label="literal T ::= n"]
32
+ first_term -> literal_1
33
+ literal_1 [label="n : 1"]
34
+ expression -> subtraction_operator
35
+ subtraction_operator [label="-"]
36
+ expression -> second_term
37
+ second_term [label="literal T ::= n"]
38
+ second_term -> literal_2
39
+ literal_2 [label="n : 2"]
40
+ }),
41
+ result.to_dot)
42
+ end
43
+
44
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+
3
+ class TestParserState < Test::Unit::TestCase
4
+ include Dhaka
5
+ def test_unique_identifier
6
+ states = (0...5).collect {|i| ParserState.new(nil, {})}
7
+ ids = Set.new
8
+ states.each do |state|
9
+ assert(/^State(\d+)$/ =~ state.unique_name)
10
+ ids << $1.to_i
11
+ end
12
+ assert_equal(5, ids.size)
13
+ end
14
+
15
+ def test_to_s_method
16
+ options = {:some_option => true}
17
+ item1 = mock()
18
+ item1.stubs(:to_s).with(options).returns("i'm item 1")
19
+ item2 = mock()
20
+ item2.stubs(:to_s).with(options).returns("i'm item 2")
21
+ state = ParserState.new(nil, {item1 => item1, item2 => item2})
22
+ assert_equal(["i'm item 1", "i'm item 2"], state.to_s(options).split("\n").sort)
23
+ end
24
+ end
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + '/simple_grammar'
3
+ require File.dirname(__FILE__) + '/nullable_grammar'
4
+ require File.dirname(__FILE__) + '/lalr_but_not_slr_grammar'
5
+ require File.dirname(__FILE__) + '/another_lalr_but_not_slr_grammar'
6
+ require File.dirname(__FILE__) + '/rr_conflict_grammar'
7
+ require File.dirname(__FILE__) + '/sr_conflict_grammar'
8
+
9
+ class ParserTest < Test::Unit::TestCase
10
+ def build_tokens(token_symbol_names)
11
+ token_symbol_names.collect {|symbol_name| Dhaka::Token.new(symbol_name, nil, nil)}
12
+ end
13
+
14
+ def setup
15
+ @grammar = SimpleGrammar
16
+ @parser = Dhaka::Parser.new(@grammar)
17
+ end
18
+
19
+ def contains(given_member, set)
20
+ set.inject(false) {|result, member| result ||= (Set.new(member) == Set.new(given_member))}
21
+ end
22
+
23
+ def assert_collection_equal(expected, actual)
24
+ assert_equal(expected.size, actual.size)
25
+ actual.each do |actual_member|
26
+ assert(contains(actual_member, expected), "Should have found #{actual_member} in expected set.")
27
+ end
28
+ end
29
+
30
+ def test_parser_generates_states_with_correct_items
31
+ expected_states = [
32
+ ['_Start_ ::= -> S # [_End_]',
33
+ 'S ::= -> E [#]',
34
+ 'E ::= -> E - T [#-]',
35
+ 'E ::= -> T [#-]',
36
+ 'T ::= -> n [#-]',
37
+ 'T ::= -> ( E ) [#-]'],
38
+ ['E ::= T -> [#)-]'],
39
+ ['T ::= n -> [#)-]'],
40
+ ['S ::= E -> [#]',
41
+ 'E ::= E -> - T [#-]'],
42
+ ['_Start_ ::= S -> # [_End_]'],
43
+ ['T ::= ( -> E ) [#)-]',
44
+ 'E ::= -> E - T [)-]',
45
+ 'E ::= -> T [)-]',
46
+ 'T ::= -> n [)-]',
47
+ 'T ::= -> ( E ) [)-]'],
48
+ ['E ::= E - -> T [#)-]',
49
+ 'T ::= -> n [#)-]',
50
+ 'T ::= -> ( E ) [#)-]'],
51
+ ['E ::= E - T -> [#)-]'],
52
+ ['T ::= ( E -> ) [#)-]',
53
+ 'E ::= E -> - T [)-]'],
54
+ ['T ::= ( E ) -> [#)-]'],
55
+ ['_Start_ ::= S # -> [_End_]']]
56
+ actual_states = @parser.send('states').collect {|state| state.items.values.collect {|item| item.to_s}}
57
+ assert_collection_equal(expected_states, actual_states)
58
+ end
59
+
60
+ def test_parser_can_be_exported_to_dot_format
61
+ dot_representation = @parser.to_dot
62
+ end
63
+
64
+ def test_parser_generates_parse_tree_given_a_stream_of_symbols
65
+ parse_tree = @parser.parse(build_tokens(['(','n','-','(','n','-','n',')',')','-','n','#', Dhaka::END_SYMBOL_NAME]))
66
+ assert_equal \
67
+ ["literal",
68
+ "term",
69
+ "literal",
70
+ "term",
71
+ "literal",
72
+ "subtraction",
73
+ "parenthetized_expression",
74
+ "subtraction",
75
+ "parenthetized_expression",
76
+ "term",
77
+ "literal",
78
+ "subtraction",
79
+ "expression",
80
+ "start"], parse_tree.linearize.collect {|node| node.production.name}
81
+ end
82
+
83
+ def get_linearized_parse_result(input, parser)
84
+ parser.parse(build_tokens(input)).parse_tree.linearize.collect {|node| node.production.name}
85
+ end
86
+
87
+ def test_with_a_grammar_with_nullables_after_terminals
88
+ grammar = NullableGrammar
89
+ parser = Dhaka::Parser.new(grammar)
90
+ parser_input = ['(','a',')', Dhaka::END_SYMBOL_NAME]
91
+ assert_equal \
92
+ ["literal_a",
93
+ "empty_element_list",
94
+ "concatenate_element_lists",
95
+ "element_list",
96
+ "tuple"], get_linearized_parse_result(parser_input, parser)
97
+ end
98
+
99
+ def test_with_a_grammar_that_is_not_SLR
100
+ grammar = LALRButNotSLRGrammar
101
+ parser = Dhaka::Parser.new(grammar)
102
+ parser_input = ['b','d','c', Dhaka::END_SYMBOL_NAME]
103
+ assert_equal(["A_d", "E_bAc", "start"], get_linearized_parse_result(parser_input, parser))
104
+ end
105
+
106
+ def test_with_another_grammar_that_is_not_SLR
107
+ grammar = AnotherLALRButNotSLRGrammar
108
+ parser = Dhaka::Parser.new(grammar)
109
+ parser_input = ['*', 'id', '=', 'id', Dhaka::END_SYMBOL_NAME]
110
+ assert_equal(["identifier", "l_value", "contents", "identifier", "l_value", "assignment"], get_linearized_parse_result(parser_input, parser))
111
+ end
112
+
113
+ def test_debug_output_with_a_grammar_that_should_generate_an_RR_conflict
114
+ fake_logger = FakeLogger.new
115
+ Dhaka::ParserState.any_instance.stubs(:unique_name).returns("StateXXX")
116
+ parser = Dhaka::Parser.new(RRConflictGrammar, fake_logger)
117
+ num_states = parser.send(:states).size
118
+ assert_equal(['Created StateXXX.'] * num_states, fake_logger.debugs[0...num_states])
119
+ assert_equal(1, fake_logger.errors.size)
120
+ assert(fake_logger.errors.first.match(/^Parser Conflict at State:\n(.+)\n(.+)\nExisting: (.+)\nNew: (.+)\nLookahead: (.+)$/))
121
+ assert_equal(["A ::= x y ->", "B ::= x y ->", "Reduce with xy A ::= x y", "Reduce with xy_again B ::= x y", "c"],
122
+ $~[1..5].sort)
123
+ end
124
+
125
+ def write_parser(parser)
126
+ File.open('parser.dot', 'w') do |file|
127
+ file << parser.to_dot
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,17 @@
1
+ class PrecedenceGrammar < Dhaka::Grammar
2
+
3
+ precedences do
4
+ left %w| * |
5
+ end
6
+
7
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
8
+ expression %w| E * F |
9
+ whatever %w| E F |, :prec => '*'
10
+ end
11
+
12
+ for_symbol('F') do
13
+ something %w| foo |
14
+ end
15
+
16
+ end
17
+
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + "/precedence_grammar"
3
+
4
+ class TestPrecedenceGrammar < Test::Unit::TestCase
5
+ def test_precedences_are_computed_correctly
6
+ assert_equal(:left, PrecedenceGrammar.production_named('expression').precedence.associativity)
7
+ assert_equal(:left, PrecedenceGrammar.production_named('whatever').precedence.associativity)
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ class RRConflictGrammar < Dhaka::Grammar
2
+
3
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
4
+ start %w| S |
5
+ end
6
+
7
+ for_symbol('S') do
8
+ a_expansion %w| A c d |
9
+ b_expansion %w| B c e |
10
+ end
11
+
12
+ for_symbol('A') do
13
+ xy %w| x y |
14
+ end
15
+
16
+ for_symbol('B') do
17
+ xy_again %w| x y |
18
+ end
19
+
20
+ end
21
+
@@ -0,0 +1,22 @@
1
+ class SimpleGrammar < Dhaka::Grammar
2
+
3
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
4
+ start %w| S # |
5
+ end
6
+
7
+ for_symbol('S') do
8
+ expression %w| E |
9
+ end
10
+
11
+ for_symbol('E') do
12
+ subtraction %w| E - T |
13
+ term %w| T |
14
+ end
15
+
16
+ for_symbol('T') do
17
+ literal %w| n |
18
+ parenthetized_expression %w| ( E ) |
19
+ end
20
+
21
+ end
22
+
@@ -0,0 +1,16 @@
1
+ class SRConflictGrammar < Dhaka::Grammar
2
+
3
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
4
+ statement %w| statement |
5
+ end
6
+
7
+ for_symbol('statement') do
8
+ if_statement %w| if_statement |
9
+ end
10
+
11
+ for_symbol('if_statement') do
12
+ if_then_statement %w| IF expr THEN statement |
13
+ if_then_else_statement %w| IF expr THEN statement ELSE statement END |
14
+ end
15
+
16
+ end
@@ -0,0 +1,17 @@
1
+ unless defined? Dhaka
2
+ require File.dirname(__FILE__) + '/../lib/dhaka'
3
+ end
4
+
5
+ require File.dirname(__FILE__) + '/fake_logger'
6
+
7
+ require 'test/unit'
8
+
9
+ begin
10
+ require 'mocha'
11
+ rescue LoadError
12
+ puts "
13
+ The tests depend on Mocha. Please install it if you wish to run them:
14
+ sudo gem install mocha
15
+ This gem is not required for using the library."
16
+ exit
17
+ end
@@ -0,0 +1,17 @@
1
+ class FakeLogger
2
+ attr_reader :warnings, :debugs, :errors
3
+ def initialize
4
+ @warnings = []
5
+ @debugs = []
6
+ @errors = []
7
+ end
8
+ def debug message
9
+ @debugs << message
10
+ end
11
+ def error message
12
+ @errors << message
13
+ end
14
+ def warn message
15
+ @warnings << message
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ # Exceptions that are caused by an invalid request from the client.
2
+ class ClientException < Exception
3
+ attr_accessor :code, :msg
4
+
5
+ def initialize(code, msg)
6
+ @code = code
7
+ @msg = msg
8
+ end
9
+
10
+ end
@@ -0,0 +1,146 @@
1
+ require 'singleton'
2
+ require 'simplerdb/query_language'
3
+
4
+ module SimplerDB
5
+
6
+ class Domain
7
+ attr_accessor :name, :items
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ @items = Hash.new { |hash, key| hash[key] = Item.new(key) }
12
+ end
13
+ end
14
+
15
+ class Item
16
+ attr_accessor :name, :attributes
17
+
18
+ def initialize(name)
19
+ @name = name
20
+ @attributes = Hash.new { |hash, key| hash[key] = [] }
21
+ end
22
+
23
+ def put_attribute(attr, replace = false)
24
+ @attributes[attr.name].clear if replace
25
+ @attributes[attr.name] << attr
26
+ end
27
+
28
+ def delete_attribute(attr)
29
+ if attr.value.nil?
30
+ @attributes[attr.name].clear
31
+ else
32
+ @attributes[attr.name].delete(attr)
33
+ end
34
+
35
+ if @attributes[attr.name].size == 0
36
+ @attributes.delete(attr.name)
37
+ end
38
+ end
39
+
40
+ def get_attributes(attribute_name = nil)
41
+ attrs = []
42
+
43
+ @attributes.each do |key, value|
44
+ if (attribute_name.nil? || attribute_name == key)
45
+ attrs += value
46
+ end
47
+ end
48
+
49
+ return attrs
50
+ end
51
+ end
52
+
53
+ class Attribute
54
+ attr_accessor :name, :value
55
+
56
+ def initialize(name, value)
57
+ @name = name
58
+ @value = value
59
+ end
60
+
61
+ def ==(other)
62
+ @name == other.name && @value == other.value
63
+ end
64
+ end
65
+
66
+ class AttributeParam < Attribute
67
+ attr_accessor :replace
68
+
69
+ def initialize(name, value, replace = false)
70
+ super(name, value)
71
+ @replace = replace
72
+ end
73
+
74
+ def to_attr
75
+ Attribute.new(self.name, self.value)
76
+ end
77
+ end
78
+
79
+ # The main SimplerDB class, containing methods that correspond to the
80
+ # AWS API.
81
+ class DB
82
+ include Singleton
83
+
84
+ def initialize
85
+ reset
86
+ end
87
+
88
+ # For testing
89
+ def reset
90
+ @domains = {}
91
+ @query_executor = QueryExecutor.new
92
+ end
93
+
94
+ def create_domain(name)
95
+ @domains[name] ||= Domain.new(name)
96
+ end
97
+
98
+ def delete_domain(name)
99
+ @domains.delete(name)
100
+ end
101
+
102
+ def list_domains(max = 100, token = 0)
103
+ doms = []
104
+ count = 0
105
+ token = 0 unless token
106
+ @domains.keys.each do |domain|
107
+ break if doms.size == max
108
+ doms << domain if count >= token.to_i
109
+ count += 1
110
+ end
111
+
112
+ if (count >= @domains.size)
113
+ return doms,nil
114
+ else
115
+ return doms,count
116
+ end
117
+ end
118
+
119
+ def get_attributes(domain_name, item_name, attribute_name = nil)
120
+ domain = @domains[domain_name]
121
+ item = domain.items[item_name]
122
+ return item.get_attributes(attribute_name)
123
+ end
124
+
125
+ def put_attributes(domain_name, item_name, attribute_params)
126
+ domain = @domains[domain_name]
127
+ item = domain.items[item_name]
128
+ attribute_params.each { |attr| item.put_attribute(attr.to_attr, attr.replace) }
129
+ end
130
+
131
+ def delete_attributes(domain_name, item_name, attributes)
132
+ domain = @domains[domain_name]
133
+ item = domain.items[item_name]
134
+ if attributes.empty?
135
+ domain.items.delete(item_name)
136
+ else
137
+ attributes.each { |attr| item.delete_attribute(attr) }
138
+ end
139
+ end
140
+
141
+ def query(domain, query, max = 100, token = 0)
142
+ @query_executor.do_query(query, @domains[domain], max, token)
143
+ end
144
+ end
145
+
146
+ end