Skip to content

Commit 0007ef5

Browse files
committed
Add ProFormA serialization of exercise files
- added factories for exercises which are associated with an exercise file - added tests for covering the ProFormA specification compliance for exercise files (#17)
1 parent 31c1dd2 commit 0007ef5

File tree

4 files changed

+125
-0
lines changed

4 files changed

+125
-0
lines changed

app/models/exercise.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,20 @@ def add_tests(test_array)
9292
end
9393
end
9494

95+
def build_proforma_xml_for_exercise_file(builder, exercise_file)
96+
if exercise_file.main
97+
proforma_file_class = 'template'
98+
else
99+
proforma_file_class = 'internal'
100+
end
101+
102+
builder.file(exercise_file.content,
103+
'filename' => exercise_file.full_file_name,
104+
'id' => exercise_file.id,
105+
'class' => proforma_file_class
106+
)
107+
end
108+
95109
def to_proforma_xml
96110
builder = Nokogiri::XML::Builder.new do |xml|
97111
xml.root('xmlns:p' => 'urn:proforma:task:v0.9.4') {
@@ -102,6 +116,11 @@ def to_proforma_xml
102116
p.send('meta-data') {
103117
p.title(self.title)
104118
}
119+
p.files {
120+
self.exercise_files.all? { |file|
121+
build_proforma_xml_for_exercise_file(p, file)
122+
}
123+
}
105124
}
106125
}
107126
end

spec/factories/exercise.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,34 @@
44
description 'Very descriptive'
55
maxrating 10
66
end
7+
8+
factory :exercise_with_single_java_main_file, class: 'Exercise' do
9+
after(:create) do |exercise|
10+
create(:single_java_main_file, exercise: exercise)
11+
end
12+
end
13+
714
end
15+
=begin
16+
category1 = LabelCategory.create(name: 'Languages')
17+
l1 = Label.create(name: 'Java', color: '006600', label_category: category1)
18+
test_framework = TestingFramework.create(name: 'JUnit 4')
19+
20+
ExerciseFile.create(main: true, content: "public class AsteriksPattern{ public static void main String[] args) { } }", path: '', solution: false, filetype: 'java', exercise: exercise3)
21+
22+
Test.create(content: "public class AsteriksPattern {
23+
public static void main(String[] args) {
24+
printAsterisk();
25+
}
26+
static void printAsterisk() {
27+
System.out.println('*****');
28+
System.out.println('*****');
29+
System.out.println('*****');
30+
System.out.println('*****');
31+
System.out.println('*****');
32+
}
33+
}", rating: 5, feedback_message: "Dein Pattern sieht noch nicht wie das Asteriks Pattern aus. Schaue es dir nochmal genauer an!", exercise: exercise3, testing_framework: test_framework)
34+
35+
exercise3.labels << l1
36+
37+
=end

spec/factories/exercise_file.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FactoryGirl.define do
2+
3+
factory :single_java_main_file, class: 'ExerciseFile' do
4+
main true
5+
content "public class AsteriksPattern{ public static void main String[] args) { } }"
6+
file_name 'Main'
7+
path ''
8+
solution false
9+
filetype 'java'
10+
end
11+
12+
end

spec/models/exercise_spec.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,68 @@
4444

4545
end
4646

47+
describe 'files' do
48+
let(:xml) {
49+
::Nokogiri::XML(
50+
FactoryGirl.create(:only_meta_data).to_proforma_xml
51+
).xpath('/root')[0]
52+
}
53+
54+
context 'no files' do
55+
56+
it 'contains a single empty <p:files>-tag' do
57+
filesContainer = xml.xpath('p:task/p:files')
58+
expect(filesContainer.size()).to be 1
59+
allFiles = xml.xpath('p:task/*/p:file')
60+
expect(allFiles.size).to be 0
61+
end
62+
63+
end
64+
65+
context 'one Java main file' do
66+
let(:xml) {
67+
::Nokogiri::XML(
68+
FactoryGirl.create(:exercise_with_single_java_main_file).to_proforma_xml
69+
).xpath('/root')[0]
70+
}
71+
72+
it 'has single /p:files/p:file tag' do
73+
print(xml)
74+
files = xml.xpath('p:task/p:files/p:file')
75+
expect(files.size()).to be 1
76+
end
77+
78+
it 'p:file tag has class="template"' do
79+
filesClass = xml.xpath('p:task/p:files/p:file/@class').first
80+
expect(filesClass.value).to eq 'template'
81+
end
82+
83+
it 'has attribute id on <p:file>-tag' do
84+
ids = xml.xpath('p:task/p:files/p:file/@id')
85+
expect(ids.size).to be 1
86+
expect(ids.first.value.size).to be > 0
87+
end
88+
89+
it 'has attribute filename on <p:file>-tag with name and extension' do
90+
file_names = xml.xpath('p:task/p:files/p:file/@filename')
91+
expect(file_names.size).to be 1
92+
expect(file_names.first.value).to eq 'Main.java'
93+
end
94+
95+
it 'has attribute class="template" on <p:file>-tag because it is the main file' do
96+
file_names = xml.xpath('p:task/p:files/p:file/@class')
97+
expect(file_names.size).to be 1
98+
expect(file_names.first.value).to eq 'template'
99+
end
100+
101+
it '<p:file> contains file contents as plain text ' do
102+
file_contents = xml.xpath('p:task/p:files/p:file/text()')
103+
expect(file_contents.size).to be 1
104+
expect(file_contents.first.content).to eq 'public class AsteriksPattern{ public static void main String[] args) { } }'
105+
end
106+
107+
end
108+
109+
end
110+
47111
end

0 commit comments

Comments
 (0)