Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getPageByReference #16

Merged
merged 4 commits into from
Oct 2, 2020
Merged

getPageByReference #16

merged 4 commits into from
Oct 2, 2020

Conversation

rodikh
Copy link
Member

@rodikh rodikh commented Sep 18, 2020

  • added method to unibit
  • added basic tests for unibit-functions

- added method to unibit
- added basic tests for unibit-functions
@rodikh rodikh requested a review from smnh September 18, 2020 12:15
- updated tests
expect(data).toBeNull();

data = unibit.getData(pageContext, 'data/fake');
expect(data).toBeNull();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smnh be aware that getPage returns undefined when not found, while getData returns null

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can improve it to return null. but validate that it won't break anything else

src/unibit.js Outdated
@@ -240,6 +240,7 @@ module.exports = class Unibit {
context.getPage = this.getPage.bind(this, context);
context.getPages = this.getPages.bind(this, context);
context.getData = this.getData.bind(this, context);
context.getPageByReference = this.getPageByReference.bind(this, context);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am having second thoughts about the name of this function.
Should it really be getPageByReference? Maybe a better name would be getPageByFilePath because it reflects what this function does.

src/unibit.js Outdated
Comment on lines 371 to 379
getPageByReference(context, reference) {
// remove extension
reference = reference.replace(/\.md$/, '');
return _.find(context.site.pages, page => {
const pageUrl = _.trim(_.get(page, 'url'), '/');
return reference === pageUrl;
});
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every page object should have relPath property with a path to the page relative to pagesDir.
Use that instead, because page.url might actually be different from page.relPath if some kind of permalink is used that places the page under a different URL than the page file.

pretty URLs:
/content/about/index.md => /content/about

permalinks:
/content/hello.md => /content/foo

---
title: Hello
permalink: /foo
---

Comment on lines 6 to 9
it('gets a page by url', () => {
let page = unibit.getPage(pageContext, 'about');
expect(page).toBe(pageContext.site.pages[0]);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use huge file just to check correct page selection.
Use data to test only what is needed:
And don't assume indexes in test data but use references

const expectedPage = {url:"...",...smallestDataNeededForTheTest},
const pages = [
  {...smallestDataNeededForTheTest},
  expectedPage,
  {...smallestDataNeededForTheTest}
]
const page = unibit.getPage({site:{pages:pages, 'about');
expect(page).toBe(expectedPage);

Comment on lines 17 to 25
const pageContext = require('./mocks/pageContext.mock.json')
it('gets pages from folder', () => {
let pages = unibit.getPages(pageContext, 'features/');
expect(pages).toStrictEqual([pageContext.site.pages[1], pageContext.site.pages[2], pageContext.site.pages[3]]);
});
it('returns empty array if not found', () => {
let pages = unibit.getPages(pageContext, 'fake/');
expect(pages).toStrictEqual([]);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, use smallest dataset for testing, no need to load huge file

expect(data).toBeNull();

data = unibit.getData(pageContext, 'data/fake');
expect(data).toBeNull();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can improve it to return null. but validate that it won't break anything else

@@ -0,0 +1,409 @@
{
"site": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this file, use the smallest data set needed to run each test.
this will make it clear what are you testing

- PR fixes
- renamed getPageByReference to getPageByFilePath
- removed mock file
src/unibit.js Outdated
@@ -367,6 +368,15 @@ module.exports = class Unibit {
return _.get(context.site.data, path, null);
}

getPageByFilePath(context, filePath) {
// remove extension
const urlPath = _.trim(filePath, '.md');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not _.trimEnd()

src/unibit.js Outdated
Comment on lines 374 to 377
return _.find(context.site.pages, page => {
const pageUrl = _.trim(_.get(page, 'relPath'), '.md');
return urlPath === pageUrl;
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, if both have .md, why to trim it?
maybe it is even better to leave extension, so if you have two pages, home.md and home.yml it will work correctly by specifying which extension user want to use

Comment on lines 5 to 11
"absPath": "/Users/rodik/Work/Stackbit/project-repos/unibit/sample/unibit-universal/content/about.md",
"relPath": "about.md",
"absDir": "/Users/rodik/Work/Stackbit/project-repos/unibit/sample/unibit-universal/content",
"relDir": "",
"url": "about/",
"basename": "about.md",
"filename": "about"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if absPath (and other props) is not used in the test you can safely remove them from mock data. Only use what is needed by the test. This way test is more strict.
Also, having your personal file system paths in a public repo looks strange

"relPath": "about.md",
"absDir": "/Users/rodik/Work/Stackbit/project-repos/unibit/sample/unibit-universal/content",
"relDir": "",
"url": "about/",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does Unibit generate url with trailing slash?
The mock data must resemble the actual data as close as possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pulled this data directly from the debugger context when running unibit.

Comment on lines +66 to +69
it('should not work with file paths', () => {
let page = unibit.getPage(pageContext, 'about.md');
expect(page).toBeUndefined();
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although sometimes it is useful to create tests that test failures, in this case, the test should be less concerned with when it fails, but when it needs to work.
Test different ways of invoking the tested function: about/, /about, /about/

Comment on lines 104 to 107
it('gets a page by url', () => {
let data = unibit.getPageByFilePath(pageContext, 'features/feature1');
expect(data).toBe(feature1Page);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should actually fail,
these functions must be strict, getPage (by URL), getPageByFilePath (by file path)

@rodikh rodikh merged commit 1af72ec into master Oct 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants