Skip to content

Commit

Permalink
Merge pull request #1349 from jplag/report-viewer/min-version
Browse files Browse the repository at this point in the history
  • Loading branch information
Kr0nox authored Nov 28, 2023
2 parents e62c91e + f9a8dbd commit 45d3442
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 78 deletions.
13 changes: 0 additions & 13 deletions .github/workflows/report-viewer-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,6 @@ jobs:
with:
node-version: "18"

- name: Set version of Report Viewer
shell: bash
run: |
VERSION=$(grep "<revision>" pom.xml | grep -oPm1 "(?<=<revision>)[^-|<]+")
MAJOR=$(echo $VERSION | cut -d '.' -f 1)
MINOR=$(echo $VERSION | cut -d '.' -f 2)
PATCH=$(echo $VERSION | cut -d '.' -f 3)
sed -i "/major/s/.*/ \"major\": $MAJOR,/" report-viewer/src/version.json
sed -i "/minor/s/.*/ \"minor\": $MINOR,/" report-viewer/src/version.json
sed -i "/patch/s/.*/ \"patch\": $PATCH/" report-viewer/src/version.json
echo "Version of Report Viewer:"
cat report-viewer/src/version.json
- name: Install and Build 🔧
working-directory: report-viewer
run: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/report-viewer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ jobs:
MAJOR=$(echo $VERSION | cut -d '.' -f 1)
MINOR=$(echo $VERSION | cut -d '.' -f 2)
PATCH=$(echo $VERSION | cut -d '.' -f 3)
sed -i "/major/s/.*/ \"major\": $MAJOR,/" report-viewer/src/version.json
sed -i "/minor/s/.*/ \"minor\": $MINOR,/" report-viewer/src/version.json
sed -i "/patch/s/.*/ \"patch\": $PATCH/" report-viewer/src/version.json
json=$(cat report-viewer/src/version.json)
json=$(echo "$json" | jq --arg MAJOR "$MAJOR" --arg MINOR "$MINOR" --arg PATCH "$PATCH" '.report_viewer_version |= { "major": $MAJOR | tonumber, "minor": $MINOR | tonumber, "patch": $PATCH | tonumber }')
echo "$json" > report-viewer/src/version.json
echo "Version of Report Viewer:"
cat report-viewer/src/version.json
Expand Down
35 changes: 19 additions & 16 deletions report-viewer/src/components/VersionInfoComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,32 @@
You are using a development version of the JPlag Report Viewer.
</div>

<div v-else-if="newestVersion.compareTo(reportViewerVersion) > 0" class="text-left text-error">
You are using an outdated version of the JPlag Report Viewer ({{
reportViewerVersion.toString()
}}).<br />
Version {{ newestVersion.toString() }} is available on
<a href="https://github.com/jplag/JPlag/releases/latest" class="text-link underline">GitHub</a
>.
</div>
<div v-else>
<div v-if="newestVersion.compareTo(reportViewerVersion) > 0" class="text-left text-error">
You are using an outdated version of the JPlag Report Viewer ({{
reportViewerVersion.toString()
}}).<br />
Version {{ newestVersion.toString() }} is available on
<a href="https://github.com/jplag/JPlag/releases/latest" class="text-link underline"
>GitHub</a
>.
</div>

<div v-else>JPlag v{{ reportViewerVersion.toString() }}</div>

<div v-else>JPlag v{{ reportViewerVersion.toString() }}</div>
<div v-if="!minimalReportVersion.isInvalid()">
The minimal version of JPlag that is supported by the viewer is v{{
minimalReportVersion.toString()
}}.
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { Version } from '@/model/Version'
import versionJson from '@/version.json'
import { ref } from 'vue'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
const reportViewerVersion: Version =
versionJson['report_viewer_version'] !== undefined
? OverviewFactory.extractVersion(versionJson['report_viewer_version'])
: new Version(-1, -1, -1)
import { minimalReportVersion, reportViewerVersion } from '@/model/Version'
const newestVersion = ref(new Version(-1, -1, -1))
Expand Down
12 changes: 12 additions & 0 deletions report-viewer/src/model/Version.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import versionJson from '@/version.json'

/**
* Version of the report viewer.
*/
Expand Down Expand Up @@ -33,4 +35,14 @@ export class Version {
public isInvalid(): boolean {
return this.major < 0 || this.minor < 0 || this.patch < 0
}

public static fromJsonField(versionField: Record<string, number> | undefined): Version {
if (versionField) {
return new Version(versionField.major, versionField.minor, versionField.patch)
}
return new Version(-1, -1, -1)
}
}

export const reportViewerVersion = Version.fromJsonField(versionJson['report_viewer_version'])
export const minimalReportVersion = Version.fromJsonField(versionJson['minimal_report_version'])
67 changes: 34 additions & 33 deletions report-viewer/src/model/factories/OverviewFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { Overview } from '../Overview'
import type { ComparisonListElement } from '../ComparisonListElement'
import type { Cluster } from '@/model/Cluster'
import { store } from '@/stores/store'
import { Version } from '../Version'
import versionJson from '@/version.json'
import { Version, minimalReportVersion, reportViewerVersion } from '../Version'
import { getLanguageParser } from '../Language'
import { Distribution } from '../Distribution'
import { MetricType } from '../MetricType'
Expand All @@ -15,11 +14,6 @@ import { TenValueDistribution } from '../TenValueDistribution'
* Factory class for creating Overview objects
*/
export class OverviewFactory extends BaseFactory {
static reportViewerVersion: Version =
versionJson['report_viewer_version'] !== undefined
? this.extractVersion(versionJson['report_viewer_version'] as Record<string, number>)
: new Version(-1, -1, -1)

/**
* Gets the overview file based on the used mode (zip, local, single).
*/
Expand All @@ -33,9 +27,9 @@ export class OverviewFactory extends BaseFactory {
*/
private static extractOverview(json: Record<string, unknown>): Overview {
const versionField = json.jplag_version as Record<string, number>
const jplagVersion = this.extractVersion(versionField)
const jplagVersion = Version.fromJsonField(versionField)

OverviewFactory.compareVersions(jplagVersion, this.reportViewerVersion)
OverviewFactory.compareVersions(jplagVersion, reportViewerVersion, minimalReportVersion)

const submissionFolder = json.submission_folder_path as Array<string>
const baseCodeFolder = json.base_code_folder_path as string
Expand Down Expand Up @@ -64,10 +58,6 @@ export class OverviewFactory extends BaseFactory {
)
}

public static extractVersion(versionField: Record<string, number>): Version {
return new Version(versionField.major, versionField.minor, versionField.patch)
}

private static extractDistributions(
json: Record<string, unknown>
): Record<MetricType, Distribution> {
Expand Down Expand Up @@ -203,29 +193,40 @@ export class OverviewFactory extends BaseFactory {
* @param jsonVersion the version of the json file
* @param reportViewerVersion the version of the report viewer
*/
static compareVersions(jsonVersion: Version, reportViewerVersion: Version) {
static compareVersions(
jsonVersion: Version,
reportViewerVersion: Version,
minimalVersion: Version = new Version(0, 0, 0)
) {
if (sessionStorage.getItem('versionAlert') === null) {
if (jsonVersion.compareTo(reportViewerVersion) !== 0) {
if (reportViewerVersion.isInvalid()) {
console.warn(
"The report viewer's version cannot be read from version.json file. Please configure it correctly."
)
} else {
console.warn(
"The result's version tag does not fit the report viewer's version. Trying to read it anyhow but be careful."
)
alert(
"The result's version(" +
jsonVersion.toString() +
") tag does not fit the report viewer's version(" +
reportViewerVersion.toString() +
'). ' +
'Trying to read it anyhow but be careful.'
)
}
if (reportViewerVersion.isInvalid()) {
console.warn(
"The report viewer's version cannot be read from version.json file. Please configure it correctly."
)
} else if (
!reportViewerVersion.isDevVersion() &&
jsonVersion.compareTo(reportViewerVersion) > 0
) {
alert(
"The result's version(" +
jsonVersion.toString() +
") is newer than the report viewer's version(" +
reportViewerVersion.toString() +
'). ' +
'Trying to read it anyhow but be careful.'
)
}

sessionStorage.setItem('versionAlert', 'true')
}
if (jsonVersion.compareTo(minimalVersion) < 0) {
throw (
"The result's version(" +
jsonVersion.toString() +
') is older than the minimal support version of the report viewer(' +
reportViewerVersion.toString() +
'). ' +
'Can not read the report.'
)
}
}
}
5 changes: 5 additions & 0 deletions report-viewer/src/version.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,10 @@
"major": 0,
"minor": 0,
"patch": 0
},
"minimal_report_version": {
"major": 4,
"minor": 0,
"patch": 0
}
}
31 changes: 19 additions & 12 deletions report-viewer/tests/unit/components/VersionInfoComponent.test.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
import VersionInfoComponent from '@/components/VersionInfoComponent.vue'
import { flushPromises, mount } from '@vue/test-utils'
import { describe, it, vi, expect } from 'vitest'
import version from '@/version.json'

vi.mock('@/version.json')
import { describe, it, vi, expect, beforeAll } from 'vitest'

Check warning on line 3 in report-viewer/tests/unit/components/VersionInfoComponent.test.ts

View workflow job for this annotation

GitHub Actions / check

'beforeAll' is defined but never used
import * as versionTsFile from '@/model/Version'
import { Version } from '@/model/Version'

describe('VersionInfoComponent', () => {
it('Render develop version', async () => {
version.report_viewer_version = mockVersionJSON(0, 0, 0)
vi.spyOn(versionTsFile, 'reportViewerVersion', 'get').mockReturnValue(mockVersionJSON(0, 0, 0))
vi.spyOn(versionTsFile, 'minimalReportVersion', 'get').mockReturnValue(mockVersionJSON(4, 0, 0))
global.fetch = vi.fn().mockResolvedValueOnce(mockVersionResponse('v4.3.0'))

const wrapper = mount(VersionInfoComponent)
await flushPromises()

expect(wrapper.text()).toContain('development version')
expect(wrapper.text()).not.toContain(
'The minimal version of JPlag that is supported by the viewer is v4.0.0.'
)
})

it('Render outdated version', async () => {
version.report_viewer_version = mockVersionJSON(4, 3, 0)
vi.spyOn(versionTsFile, 'reportViewerVersion', 'get').mockReturnValue(mockVersionJSON(4, 3, 0))
vi.spyOn(versionTsFile, 'minimalReportVersion', 'get').mockReturnValue(mockVersionJSON(4, 0, 0))
global.fetch = vi.fn().mockResolvedValueOnce(mockVersionResponse('v4.4.0'))

const wrapper = mount(VersionInfoComponent)
await flushPromises()

expect(wrapper.text()).toContain('outdated version')
expect(wrapper.text()).toContain(
'The minimal version of JPlag that is supported by the viewer is v4.0.0.'
)
})

it('Render latest version', async () => {
version.report_viewer_version = mockVersionJSON(4, 3, 0)
vi.spyOn(versionTsFile, 'reportViewerVersion', 'get').mockReturnValue(mockVersionJSON(4, 3, 0))
vi.spyOn(versionTsFile, 'minimalReportVersion', 'get').mockReturnValue(mockVersionJSON(4, 0, 0))
global.fetch = vi.fn().mockResolvedValueOnce(mockVersionResponse('v4.3.0'))

const wrapper = mount(VersionInfoComponent)
await flushPromises()

expect(wrapper.text()).toContain('JPlag v4.3.0')
expect(wrapper.text()).toContain(
'The minimal version of JPlag that is supported by the viewer is v4.0.0.'
)
})
})

Expand All @@ -47,9 +58,5 @@ function mockVersionResponse(version: string) {
}

function mockVersionJSON(major: number, minor: number, patch: number) {
return {
major: major,
minor: minor,
patch: patch
}
return new Version(major, minor, patch)
}
73 changes: 73 additions & 0 deletions report-viewer/tests/unit/model/factories/OutdatedOverview.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"jplag_version": { "major": 3, "minor": 0, "patch": 0 },
"submission_folder_path": ["files"],
"base_code_folder_path": "",
"language": "Javac based AST plugin",
"file_extensions": [".java", ".JAVA"],
"submission_id_to_display_name": { "A": "A", "B": "B", "C": "C", "D": "D" },
"submission_ids_to_comparison_file_name": {
"A": { "B": "B-A.json", "C": "A-C.json", "D": "D-A.json" },
"B": { "A": "B-A.json", "C": "B-C.json", "D": "B-D.json" },
"C": { "A": "A-C.json", "B": "B-C.json", "D": "D-C.json" },
"D": { "A": "D-A.json", "B": "B-D.json", "C": "D-C.json" }
},
"failed_submission_names": [],
"excluded_files": [],
"match_sensitivity": 9,
"date_of_execution": "12/07/23",
"execution_time": 12,
"distributions": {
"MAX": [
1, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
],
"AVG": [
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
]
},
"top_comparisons": [
{
"first_submission": "A",
"second_submission": "C",
"similarities": { "AVG": 0.9960435212660732, "MAX": 0.9960435212660732 }
},
{
"first_submission": "D",
"second_submission": "A",
"similarities": { "AVG": 0.751044776119403, "MAX": 0.947289156626506 }
},
{
"first_submission": "D",
"second_submission": "C",
"similarities": { "AVG": 0.751044776119403, "MAX": 0.947289156626506 }
},
{
"first_submission": "B",
"second_submission": "D",
"similarities": { "AVG": 0.28322981366459626, "MAX": 0.8085106382978723 }
},
{
"first_submission": "B",
"second_submission": "A",
"similarities": { "AVG": 0.2378472222222222, "MAX": 0.9716312056737588 }
},
{
"first_submission": "B",
"second_submission": "C",
"similarities": { "AVG": 0.2378472222222222, "MAX": 0.9716312056737588 }
}
],
"clusters": [
{
"average_similarity": 94.746956,
"strength": 0.0,
"members": ["C", "A", "B", "D"]
}
],
"total_comparisons": 6
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { HundredValueDistribution } from '@/model/HundredValueDistribution'
import { TenValueDistribution } from '@/model/TenValueDistribution'
import validNew from './ValidNewOverview.json'
import validOld from './ValidOldOverview.json'
import outdated from './OutdatedOverview.json'

const store = {
state: {
Expand Down Expand Up @@ -175,3 +176,10 @@ describe('Test JSON to Overview', () => {
})
})
})

describe('Outdated JSON to Overview', () => {
it('Outdated version', async () => {
store.state.files['overview.json'] = JSON.stringify(outdated)
expect(() => OverviewFactory.getOverview()).rejects.toThrowError()
})
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"jplag_version": { "major": 0, "minor": 0, "patch": 0 },
"jplag_version": { "major": 4, "minor": 0, "patch": 0 },
"submission_folder_path": ["files"],
"base_code_folder_path": "",
"language": "Javac based AST plugin",
Expand Down

0 comments on commit 45d3442

Please sign in to comment.