|
193 | 193 | end |
194 | 194 |
|
195 | 195 | describe '#execute' do |
196 | | - # @todo: test isolation semantics! |
197 | | - |
| 196 | + let(:st) { RDF::Statement(:s, RDF::URI('p'), 'o') } |
| 197 | + |
198 | 198 | context 'after rollback' do |
199 | 199 | before { subject.rollback } |
200 | 200 |
|
|
203 | 203 | .to raise_error RDF::Transaction::TransactionError |
204 | 204 | end |
205 | 205 | end |
| 206 | + |
| 207 | + context 'when :read_committed' do |
| 208 | + it 'does not read uncommitted statements' do |
| 209 | + unless subject.isolation_level == :read_uncommitted |
| 210 | + read_tx = klass.new(repository, mutable: true) |
| 211 | + subject.insert(st) |
| 212 | + |
| 213 | + expect(read_tx.statements).not_to include(st) |
| 214 | + end |
| 215 | + end |
| 216 | + |
| 217 | + it 'reads committed statements' do |
| 218 | + if subject.isolation_level == :read_committed |
| 219 | + read_tx = klass.new(repository) |
| 220 | + subject.insert(st) |
| 221 | + subject.execute |
| 222 | + |
| 223 | + expect(read_tx.statements).to include(st) |
| 224 | + end |
| 225 | + end |
| 226 | + end |
| 227 | + |
| 228 | + context 'when :repeatable_read' do |
| 229 | + it 'does not read committed statements already read' do |
| 230 | + if subject.isolation_level == :repeatable_read || |
| 231 | + subject.isolation_level == :snapshot || |
| 232 | + subject.isolation_level == :serializable |
| 233 | + read_tx = klass.new(repository) |
| 234 | + subject.insert(st) |
| 235 | + subject.execute |
| 236 | + |
| 237 | + expect(read_tx.statements).not_to include(st) |
| 238 | + end |
| 239 | + end |
| 240 | + end |
| 241 | + |
| 242 | + context 'when :snapshot' do |
| 243 | + it 'does not read committed statements' do |
| 244 | + if subject.isolation_level == :snapshot || |
| 245 | + subject.isolation_level == :serializable |
| 246 | + read_tx = klass.new(repository) |
| 247 | + subject.insert(st) |
| 248 | + subject.execute |
| 249 | + |
| 250 | + expect(read_tx.statements).not_to include(st) |
| 251 | + end |
| 252 | + end |
| 253 | + |
| 254 | + it 'reads current transaction state' do |
| 255 | + if subject.isolation_level == :snapshot || |
| 256 | + subject.isolation_level == :serializable |
| 257 | + subject.insert(st) |
| 258 | + expect(subject.statements).to include(st) |
| 259 | + end |
| 260 | + end |
| 261 | + end |
| 262 | + |
| 263 | + context 'when :serializable' do |
| 264 | + it 'raises an error if conflicting changes are present' do |
| 265 | + if subject.isolation_level == :serializable |
| 266 | + subject.insert(st) |
| 267 | + repository.insert(st) |
| 268 | + |
| 269 | + expect { subject.execute } |
| 270 | + .to raise_error RDF::Transaction::TransactionError |
| 271 | + end |
| 272 | + end |
| 273 | + end |
206 | 274 | end |
207 | 275 |
|
208 | 276 | describe '#rollback' do |
|
0 commit comments