From 8ec35c69a308081f267d0e3a242d76f34edbb25c Mon Sep 17 00:00:00 2001 From: Tim Mackinnon Date: Sun, 24 Mar 2019 23:31:16 +0000 Subject: [PATCH 1/4] Publish test results along with exercise so its easy to see if the solution is passing or not (helps with mentoring, but also for other users to understand if a solution passes or not) --- .../ExercismTools/ExercismExercise.class.st | 11 +++++++++-- .../ExercismTools/ExercismManager.class.st | 2 +- dev/src/ExercismTools/TestResult.extension.st | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 dev/src/ExercismTools/TestResult.extension.st diff --git a/dev/src/ExercismTools/ExercismExercise.class.st b/dev/src/ExercismTools/ExercismExercise.class.st index 9aef9783..a784de6c 100644 --- a/dev/src/ExercismTools/ExercismExercise.class.st +++ b/dev/src/ExercismTools/ExercismExercise.class.st @@ -281,12 +281,19 @@ ExercismExercise >> solutionId [ { #category : #accessing } ExercismExercise >> solutionSources [ - | sources | + "Answer a Dictionary of filename to source code mappings for the solution that will be saved on Exercism" + + | sources testResult resultDictionary | sources := ExTonelWriter new mappedSnapshot: self exercisePackageTag snapshot. + testResult := [ self testCase suite run] on: Error do: [ TestResult new ]. + resultDictionary := OrderedDictionary new + at: 'TestResults.txt' put: testResult exercismSummary; + yourself. + ^ (self solutionClasses collect: [ :c | c name ]) - inject: Dictionary new + inject: resultDictionary into: [ :result :c | result at: c , '.st' put: (sources at: c); diff --git a/dev/src/ExercismTools/ExercismManager.class.st b/dev/src/ExercismTools/ExercismManager.class.st index 81a85597..404b1e94 100644 --- a/dev/src/ExercismTools/ExercismManager.class.st +++ b/dev/src/ExercismTools/ExercismManager.class.st @@ -38,7 +38,7 @@ ExercismManager class >> isUserMode [ "Answer true if exercism is loaded in a clean image with no dev tools" ^ ((IceRepository registry collect: [ :repo | repo name ])) asArray - = #('iceberg' 'pharo' 'pharo-exercism') + = #('iceberg' 'pharo' 'pharo-smalltalk') and: [ (RPackageOrganizer default packageNamed: 'ExercismDev' ifAbsent: [ nil ]) isNil ] diff --git a/dev/src/ExercismTools/TestResult.extension.st b/dev/src/ExercismTools/TestResult.extension.st new file mode 100644 index 00000000..aa7f7cba --- /dev/null +++ b/dev/src/ExercismTools/TestResult.extension.st @@ -0,0 +1,19 @@ +Extension { #name : #TestResult } + +{ #category : #'*ExercismTools' } +TestResult >> exercismSummary [ + ^String streamContents: [ :s | s + nextPutAll: 'Tested on: '; + nextPutAll: self timeStamp asLocalStringYMDHM; + crlf; + nextPutAll: self runCount printString; + nextPutAll: ' run, '; + nextPutAll: self expectedPassCount printString; + nextPutAll: ' passes, '; + nextPutAll: self skippedCount printString; + nextPutAll: ' skipped, '; + nextPutAll: self unexpectedFailureCount printString; + nextPutAll: ' failures, '; + nextPutAll: self unexpectedErrorCount printString; + nextPutAll:' errors ' ] +] From 7f35d55a9a8ac2e15da6396af39ecd7e26acd719 Mon Sep 17 00:00:00 2001 From: Tim Mackinnon Date: Sun, 24 Mar 2019 23:45:18 +0000 Subject: [PATCH 2/4] Fix error catching older exercise format (without meta-data) --- dev/src/ExercismTools/ClyExercismFetchCommand.class.st | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dev/src/ExercismTools/ClyExercismFetchCommand.class.st b/dev/src/ExercismTools/ClyExercismFetchCommand.class.st index 7873e722..32336d82 100644 --- a/dev/src/ExercismTools/ClyExercismFetchCommand.class.st +++ b/dev/src/ExercismTools/ClyExercismFetchCommand.class.st @@ -70,7 +70,11 @@ ClyExercismFetchCommand >> execute [ submission ifNotNil: [ UIManager default inform: 'Success, Happy Coding'. - self browser selectClass: submission exercise testCase ] + submission exercise + ifNil: [ + ExDomainError signal: 'Missing exercise meta-data' ] + ifNotNil: [ :exercise | + self browser selectClass: exercise testCase ]] ] on: ExDomainError do: [ :ex | self reportError: ex for: (submission ifNotNil: [ :s | s exerciseId ]) ] From 0518b06002382d20f260e470e37c9064f94a0cab Mon Sep 17 00:00:00 2001 From: Tim Mackinnon Date: Mon, 25 Mar 2019 00:02:17 +0000 Subject: [PATCH 3/4] Better handle old exercise format --- dev/src/ExercismTools/ExercismTest.class.st | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/src/ExercismTools/ExercismTest.class.st b/dev/src/ExercismTools/ExercismTest.class.st index 3fa9e4ed..dfb169db 100644 --- a/dev/src/ExercismTools/ExercismTest.class.st +++ b/dev/src/ExercismTools/ExercismTest.class.st @@ -19,7 +19,7 @@ ExercismTest class >> createExerciseAfter: anotherTestCase [ ^ (ExercismExercise for: self) unlockedBy: ((anotherTestCase notNil and: [ anotherTestCase isObsolete not ]) - ifTrue: [ anotherTestCase exercise ] + ifTrue: [ [anotherTestCase exercise] on: SubclassResponsibility do: [ nil ] ] ifFalse: [ nil ]); yourself ] From cad5af69d472c359528636e475fd2ea9893575d8 Mon Sep 17 00:00:00 2001 From: Tim Mackinnon Date: Mon, 25 Mar 2019 00:11:05 +0000 Subject: [PATCH 4/4] Fix broken test, as we now get a test result as a source submission --- dev/src/ExercismTests/ExercismExerciseTest.class.st | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev/src/ExercismTests/ExercismExerciseTest.class.st b/dev/src/ExercismTests/ExercismExerciseTest.class.st index e17110ea..167ca44d 100644 --- a/dev/src/ExercismTests/ExercismExerciseTest.class.st +++ b/dev/src/ExercismTests/ExercismExerciseTest.class.st @@ -136,11 +136,12 @@ ExercismExerciseTest >> testSolutionSources [ sources := TestmanyTest exercise solutionSources. classes := {Testmany. TestOtherClass}. - classNames := classes collect: [ :c | c name, '.st' ]. + classNames := (classes collect: [ :c | c name, '.st' ]) copyWithFirst: 'TestResults.txt'. self assertCollection: sources keys asSet equals: classNames asSet. - (sources at: classNames first) should includeSubstring: '#name : #', classes first name. + (sources at: classNames first) should includeSubstring: 'Tested on:'. + (sources at: classNames second) should includeSubstring: '#name : #', classes first name. (sources at: classNames last) should includeSubstring: '#name : #', classes last name. ]