Skip to content

Commit

Permalink
Generalize src/* IFC references to prepare for .obj support.
Browse files Browse the repository at this point in the history
  • Loading branch information
pablo-mayrgundter committed Mar 28, 2023
1 parent 719ed31 commit 5e39ab2
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 29 deletions.
4 changes: 1 addition & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ const esModules = [
module.exports = {
verbose: false,
testEnvironment: 'jsdom',
testPathIgnorePatterns: [
'src/Share.test.js',
],
testPathIgnorePatterns: [],
transform: {
'\\.[jt]sx?$': 'babel-jest',
'^.+\\.svg$': '<rootDir>/svgTransform.js',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bldrs",
"version": "1.0.0-r654",
"version": "1.0.0-r658",
"main": "src/index.jsx",
"license": "MIT",
"homepage": "https://github.com/bldrs-ai/Share",
Expand Down
2 changes: 1 addition & 1 deletion src/BaseRoutes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes)
*
* which when fully expanded becomes:
*
* http://host/share/v/p/indec.ifc
* http://host/share/v/p/index.ifc
* http://host/share/v/gh/bldrs-ai/Share/main/public/index.ifc
*
* @see https://github.com/bldrs-ai/Share/wiki/Design#ifc-scene-load
Expand Down
1 change: 0 additions & 1 deletion src/Components/About/AboutControl.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default function AboutControl() {
setIsDialogDisplayed(value)
}

// eslint-disable-next-line no-unused-vars
const setIsDialogDisplayedForDialog = () => {
setIsDialogDisplayed(false)
setCookieBoolean({component: 'about', name: 'isFirstTime', value: false})
Expand Down
38 changes: 38 additions & 0 deletions src/MimeType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export const supportedTypes = ['ifc', 'obj']


/**
* @param {string} ext
* @return {boolean} Is supported
*/
export function isExtensionSupported(ext) {
return ext.match(/(?:ifc|obj)/i)
}


/**
* @param {string} strWithSuffix
* @return {boolean} Is supported
*/
export function pathSuffixSupported(pathWithSuffix) {
const lastDotNdx = pathWithSuffix.lastIndexOf('.')
if (lastDotNdx === -1) {
return false
}
return isExtensionSupported(pathWithSuffix.substring(lastDotNdx + 1))
}


/**
* @param {string} filepath
* @return {Array.<string>}
*/
export function splitAroundExtension(filepath) {
const splitRegex = /\.(?:ifc|obj)/i
const match = splitRegex.exec(filepath)
if (!match) {
throw new Error('Filepath must contain ".(ifc|obj)" (case-insensitive)')
}
const parts = filepath.split(splitRegex)
return {parts, match}
}
19 changes: 11 additions & 8 deletions src/Share.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import React, {useEffect, useMemo, useRef} from 'react'
import {useNavigate, useParams} from 'react-router-dom'
import CssBaseline from '@mui/material/CssBaseline'
import {ThemeProvider} from '@mui/material/styles'
import Styles from './Styles'
import CadView, {searchIndex} from './Containers/CadView'
import WidgetApi from './WidgetApi/WidgetApi'
import useStore from './store/useStore'
import useShareTheme from './theme/Theme'
import debug from './utils/debug'
import {handleBeforeUnload} from './utils/event'
import Styles from './Styles'
import {splitAroundExtension} from './MimeType'


/**
Expand Down Expand Up @@ -115,7 +116,14 @@ export function navToDefault(navigate, appPrefix) {
*
* @param {string} installPrefix e.g. /share
* @param {string} pathPrefix e.g. /share/v/p
* @param {object} urlParams e.g. .../:org/:repo/:branch/*
* @param {object} urlParams e.g.:
* .../:org/:repo/:branch/ with .../a/b/c/d
* becomes:
* {
* '*': 'a/b/c/d',
* 'org': 'a',
* ...
* }
* @return {object}
*/
export function getModelPath(installPrefix, pathPrefix, urlParams) {
Expand All @@ -125,12 +133,7 @@ export function getModelPath(installPrefix, pathPrefix, urlParams) {
if (filepath === '') {
return null
}
const splitRegex = /\.ifc/i
const match = splitRegex.exec(filepath)
if (!match) {
throw new Error('Filepath must contain ".ifc" (case-insensitive)')
}
const parts = filepath.split(splitRegex)
const {parts, match} = splitAroundExtension(filepath)
filepath = `/${parts[0]}${match[0]}`
if (pathPrefix.endsWith('new') || pathPrefix.endsWith('/p')) {
// * param is defined in ../Share.jsx, e.g.:
Expand Down
22 changes: 15 additions & 7 deletions src/Share.test.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import {getModelPath} from './Share'


jest.mock('three')


describe('Share', () => {
it('getModelPath parses ifc filepaths', () => {
const urlParams = {'*': 'as_Ifcdf.ifc/1234'}
expect(getModelPath('/share', '/share/v/p', urlParams)).toStrictEqual({
it('getModelPath parses ifc and obj filepaths', () => {
expect(getModelPath('/share', '/share/v/p', {'*': 'as_Ifcdf.ifc/1234'})).toStrictEqual({
filepath: '/as_Ifcdf.ifc',
eltPath: '/1234',
})
expect(getModelPath('/share', '/share/v/p', {'*': 'as_Ifcdf.obj/1234'})).toStrictEqual({
filepath: '/as_Ifcdf.obj',
eltPath: '/1234',
})
})


it('getModelPath parses mixed-case ifc filepaths', () => {
['ifc', 'Ifc', 'IFC', 'IfC', 'iFc', 'IFc'].forEach((ext) => {
const urlParams = {'*': `as_Ifcdf.${ext}/1234`}
expect(getModelPath('/share', '/share/v/p', urlParams)).toStrictEqual({
filepath: `/as_Ifcdf.${ext}`,
[
'ifc', 'Ifc', 'IFC', 'IfC', 'iFc', 'IFc',
'obj', 'Obj', 'OBJ', 'ObJ', 'oBj', 'OBj',
].forEach((ext) => {
expect(getModelPath('/share', '/share/v/p', {'*': `as_${ext}df.${ext}/1234`})).toStrictEqual({
filepath: `/as_${ext}df.${ext}`,
eltPath: '/1234',
})
})
Expand Down
17 changes: 10 additions & 7 deletions src/ShareRoutes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ import {
useLocation,
useNavigate,
} from 'react-router-dom'
import {assertDefined} from './utils/assert'
import Share from './Share'
import debug from './utils/debug'
import {assertDefined} from './utils/assert'
import {handleBeforeUnload} from './utils/event'
import Share from './Share'
import {pathSuffixSupported} from './MimeType'


/**
* For URL design see: https://github.com/bldrs-ai/Share/wiki/URL-Structure
*
* A new model path will cause a new instance of CadView to be
* instantiated, including a new IFC.js viewer. Thus, each model has
* its own IFC.js/three.js context.
* instantiated. CadView will invoke the model loader and creates a
* THREE.Scene. This scene is currently not re-used
*
* For example, a first page load of:
*
Expand Down Expand Up @@ -110,7 +111,7 @@ function Forward({appPrefix}) {
*/
export function looksLikeLink(input) {
assertDefined(input)
return input.toLowerCase().endsWith('.ifc') && (
return pathSuffixSupported(input) && (
input.startsWith('http') ||
input.startsWith('/') ||
input.startsWith('bldrs') ||
Expand Down Expand Up @@ -170,9 +171,11 @@ const pathParts = [
]


// TODO(pablo): this is pretty ad-hoc. Could be unified with MimeType
// parsing.
/**
* Matches strings like '/org/repo/branch/dir1/dir2/file.ifc' with
* an optional host prefix.
* Matches strings like '/org/repo/branch/dir1/dir2/file.(ifc|obj)'
* with an optional host prefix.
*/
const re = new RegExp(`^/${pathParts.join('/')}$`)

Expand Down
28 changes: 27 additions & 1 deletion src/ShareRoutes.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import {
looksLikeLink,
trimToPath,
githubUrlOrPathToSharePath} from './ShareRoutes'
import {supportedTypes} from './MimeType'


jest.mock('three')


// All paths here are .ifc but tests should use these as a template to
// replace with all supporte suffixes.
const path = '/org/repo/branch/file.ifc'
const pathAbc = '/org/repo/branch/a/b/c/file.ifc'
const pathBlob = '/org/repo/blob/branch/file.ifc'
const pathBlobAbc = '/org/repo/blob/branch/a/b/c/file.ifc'
const tests = [
const testTemplates = [
{s: 'http://www.github.com/org/repo/blob/branch/file.ifc', out: pathBlob},
{s: 'http://github.com/org/repo/blob/branch/file.ifc', out: pathBlob},
{s: 'http://www.github.com/org/repo/blob/branch/a/b/c/file.ifc', out: pathBlobAbc},
Expand All @@ -33,6 +36,29 @@ const tests = [
]


/**
* Replace the tests above by using them a template for paths with
* different filetypes.
*
* @return {Array.<object>}
*/
function expandTestTemplates() {
const replaced = []
for (const test of testTemplates) {
for (const ext of supportedTypes) {
const subIn = test.s.replace(/.ifc/, `.${ext}`)
const subOut = test.out.replace(/.ifc/, `.${ext}`)
replaced.push({s: subIn, out: subOut})
}
}
// .ifc is one of the supported types, so don't need append original array
return replaced
}

// This is the actual array of tests used for the tests below.
const tests = expandTestTemplates()


describe('ShareRoutes', () => {
test('looksLikeLink', () => {
tests.forEach((pair) => {
Expand Down

0 comments on commit 5e39ab2

Please sign in to comment.