module Tests; from Questions import Question, PointValue; from StudentFunctionality import Student; from MainUIFunctionality import all; export all; object Test is components: questions:QuestionGroup*, time:timeLimit; description: (* A Test represents a collection of questions that have been compiled into a test that can be taken, and the time limit for the test. *); end Test; object timeLimit is integer; object QuestionGroup is components: h:Header and qs:Question*; description: (* A question group is a group of questions with a header to give special instructions for the questions. *); end QuestionGroup; object Header is string; object PracticeTest inherits from Test description: (* A PracticeTest is a test that has been made for the purpose of helping a student. It does not require a proctor. *); end PracticeTest; object ProctorTest inherits from Test description: (* A ProctorTest represents a test that has been made, and is ready to be proctored to students. *); end ProctorTest; object TakenTest inherits from Test components: answers:GivenAnswer*, flag:InProgress, name:Student; description: (* A TakenTest object is a test that has been taken, but not yet graded. It contains all the questions from the test, as well as the student's answers. *); end TakenTest; object GivenAnswer is string; object FormattedAnswer inherits from GivenAnswer components: fa:FormattedAnswerText; end; object FormattedAnswerText is s:string or fs:FormattedString; object InProgress is boolean; object SubmittedTests is TakenTest*; object GradedTest inherits from TakenTest components: s:Score*, g:Grade, c:Comment*; description: (* A GradedTest is a test that has been taken and graded. It contains the score recieved on each question and the total grade, along with the components of a TakenTest. *); end GradedTest; object Score is real; object Grade is real; object Comment is string; operation CreateBlankTest is outputs: t:Test; description: (* Creates a new, empty test. *); end; operation InsertQuestionGroup is inputs: t:Test, qg:QuestionGroup; outputs: t':Test; description: (* Adds the given question group to the test. *); postcondition: (* * The question group is now part of the test, and the test is * otherwise unchanged. *) forall (qg':QuestionGroup) (qg' in t'.questions) iff ((qg' = qg) or (qg' in t.questions)); end; operation DeleteQuestionGroup is inputs: t:Test, qg:QuestionGroup; outputs: t':Test; description: (* Removes the given question group from the test. *); postcondition: (* * The question group no longer part of the test, and the test is * otherwise unchanged. *) forall (qg':QuestionGroup) (qg' in t'.questions) iff ((qg' != qg) or (qg' in t.questions)); end; operation SetPointValue is inputs: q:Question, pv:PointValue; outputs: q':Question; description: (* Sets the point value of the given question. *); postcondition: (* * The output Question has the point value, pv. *) q'.pv = pv; end; end Tests;