forked from cybrespace/pinafore
		
	
							parent
							
								
									32981ffeb2
								
							
						
					
					
						commit
						d5eac4e119
					
				
					 1 changed files with 100 additions and 33 deletions
				
			
		
							
								
								
									
										133
									
								
								CONTRIBUTING.md
									
										
									
									
									
								
							
							
						
						
									
										133
									
								
								CONTRIBUTING.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,19 +1,6 @@
 | 
			
		|||
# Contributing to Pinafore
 | 
			
		||||
 | 
			
		||||
## Caveats
 | 
			
		||||
 | 
			
		||||
Please note that this project is _very_ beta right now, and I'm 
 | 
			
		||||
not in a good position to accept large PRs for 
 | 
			
		||||
big new features.
 | 
			
		||||
 | 
			
		||||
I'm making my code open-source for the sake of
 | 
			
		||||
transparency and because it's the right thing to do, but I'm hesitant
 | 
			
		||||
to start nurturing a community because of 
 | 
			
		||||
[all that entails](https://nolanlawson.com/2017/03/05/what-it-feels-like-to-be-an-open-source-maintainer/).
 | 
			
		||||
 | 
			
		||||
So I may not be very responsive to PRs or issues. Thanks for understanding.
 | 
			
		||||
 | 
			
		||||
## Development
 | 
			
		||||
## Dev server
 | 
			
		||||
 | 
			
		||||
To run a dev server with hot reloading:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,9 +24,17 @@ Automatically fix most linting issues:
 | 
			
		|||
 | 
			
		||||
    npm run lint-fix
 | 
			
		||||
 | 
			
		||||
## Testing
 | 
			
		||||
## Integration tests
 | 
			
		||||
 | 
			
		||||
Testing requires running Mastodon itself, meaning the [Mastodon development guide](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md) is relevant here. In particular, you'll need a recent version of Ruby, Redis, and Postgres running.
 | 
			
		||||
Integration tests use [TestCafé](https://devexpress.github.io/testcafe/) and a live local Mastodon instance
 | 
			
		||||
running on `localhost:3000`.
 | 
			
		||||
 | 
			
		||||
### Running integration tests
 | 
			
		||||
 | 
			
		||||
The integration tests require running Mastodon itself,
 | 
			
		||||
meaning the[Mastodon development guide](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md)
 | 
			
		||||
is relevant here. In particular, you'll need a recent 
 | 
			
		||||
version of Ruby, Redis, and Postgres running. For a full list of deps, see `bin/setup-mastodon-in-travis.sh`.
 | 
			
		||||
 | 
			
		||||
Run integration tests, using headless Chrome by default:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +49,7 @@ Run tests for a particular browser:
 | 
			
		|||
    BROWSER=safari npm run test-browser
 | 
			
		||||
    BROWSER=edge npm run test-browser
 | 
			
		||||
 | 
			
		||||
## Testing in development mode
 | 
			
		||||
### Testing in development mode
 | 
			
		||||
 | 
			
		||||
In separate terminals:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -68,33 +63,46 @@ In separate terminals:
 | 
			
		|||
 | 
			
		||||
3\. Run a debuggable TestCafé instance:
 | 
			
		||||
 | 
			
		||||
    npx testcafe --hostname localhost --skip-js-errors --debug-mode firefox tests/spec
 | 
			
		||||
    npx testcafe --hostname localhost --skip-js-errors --debug-mode chrome tests/spec
 | 
			
		||||
 | 
			
		||||
If you want to export the current data in the Mastodon instance as canned data, 
 | 
			
		||||
so that it can be loaded later, run:
 | 
			
		||||
### Test conventions
 | 
			
		||||
 | 
			
		||||
    npm run backup-mastodon-data
 | 
			
		||||
The tests have a naming convention:
 | 
			
		||||
 | 
			
		||||
## Writing tests
 | 
			
		||||
 | 
			
		||||
Tests use [TestCafé](https://devexpress.github.io/testcafe/). The tests have a naming convention:
 | 
			
		||||
 | 
			
		||||
* `0xx-test-name.js`: tests that don't modify the Mastodon database (post, delete, follow, etc.)
 | 
			
		||||
* `1xx-test-name.js`: tests that do modify the Mastodon database
 | 
			
		||||
* `0xx-test-name.js`: tests that don't modify the Mastodon database (read-only)
 | 
			
		||||
* `1xx-test-name.js`: tests that do modify the Mastodon database (read-write)
 | 
			
		||||
 | 
			
		||||
In principle the `0-` tests don't have to worry about
 | 
			
		||||
clobbering each other, whereas the `1-` ones do.
 | 
			
		||||
 | 
			
		||||
## Debugging Webpack
 | 
			
		||||
### Mastodon used for testing
 | 
			
		||||
 | 
			
		||||
The Webpack Bundle Analyzer `report.html` and `stats.json` are available publicly via e.g.:
 | 
			
		||||
There are two parts to the Mastodon data used for testing:
 | 
			
		||||
 | 
			
		||||
- [dev.pinafore.social/report.html](https://dev.pinafore.social/report.html)
 | 
			
		||||
- [dev.pinafore.social/stats.json](https://dev.pinafore.social/stats.json)
 | 
			
		||||
1. A Postgres dump and a tgz containing the media files, located in `fixtures`
 | 
			
		||||
2. A script that populates the Mastodon backend with test data (`restore-mastodon-data.js`).
 | 
			
		||||
 | 
			
		||||
This is also available locally after `npm run build` at `.sapper/client/report.html`.
 | 
			
		||||
The reason we don't use a Postgres dump for everything 
 | 
			
		||||
is that Mastodon will ignore changes made after a certain period of time, and we
 | 
			
		||||
don't want our tests to randomly start breaking one day. Running the script ensures that statuses,
 | 
			
		||||
favorites, boosts, etc. are all "fresh".
 | 
			
		||||
 | 
			
		||||
## Updating Mastodon used for testing
 | 
			
		||||
### Updating the test data
 | 
			
		||||
 | 
			
		||||
You probably don't want to do this, as the `0xx` tests are pretty rigidly defined against the test data.
 | 
			
		||||
Write a `1xx` test instead and insert what you need on-the-fly.
 | 
			
		||||
 | 
			
		||||
If you really need to, though, you can either:
 | 
			
		||||
 | 
			
		||||
1. Add new test data to `mastodon-data.js`
 | 
			
		||||
 | 
			
		||||
or
 | 
			
		||||
 | 
			
		||||
1. Comment out `await restoreMastodonData()` in `run-mastodon.js`
 | 
			
		||||
2. Make your changes manually to the live Mastodon
 | 
			
		||||
3. Run the steps in the next section to back it up to `fixtures/`
 | 
			
		||||
 | 
			
		||||
### Updating the Mastodon version
 | 
			
		||||
 | 
			
		||||
1. Run `rm -fr mastodon` to clear out all Mastodon data
 | 
			
		||||
1. Comment out `await restoreMastodonData()` in `run-mastodon.js` to avoid actually populating the database with statuses/favorites/etc.
 | 
			
		||||
| 
						 | 
				
			
			@ -111,3 +119,62 @@ Check `mastodon.log` if you have any issues.
 | 
			
		|||
 | 
			
		||||
There are also some unit tests that run in Node using Mocha. You can find them in `tests/unit` and
 | 
			
		||||
run them using `npm run test-unit`.
 | 
			
		||||
 | 
			
		||||
## Debugging Webpack
 | 
			
		||||
 | 
			
		||||
The Webpack Bundle Analyzer `report.html` and `stats.json` are available publicly via e.g.:
 | 
			
		||||
 | 
			
		||||
- [dev.pinafore.social/report.html](https://dev.pinafore.social/report.html)
 | 
			
		||||
- [dev.pinafore.social/stats.json](https://dev.pinafore.social/stats.json)
 | 
			
		||||
 | 
			
		||||
This is also available locally after `npm run build` at `.sapper/client/report.html`.
 | 
			
		||||
 | 
			
		||||
## Codebase overview
 | 
			
		||||
 | 
			
		||||
Pinafore uses [SvelteJS](https://svelte.technology) and [SapperJS](https://sapper.svelte.technology). Most of it is a fairly typical Svelte/Sapper project, but there
 | 
			
		||||
are some quirks, which are described below. This list of quirks is non-exhaustive.
 | 
			
		||||
 | 
			
		||||
### Prebuild process
 | 
			
		||||
 | 
			
		||||
The `template.html` is itself templated. The "template template" has some inline scripts, CSS, and SVGs
 | 
			
		||||
injected into it during the build process. SCSS is used for global CSS and themed CSS, but inside of the
 | 
			
		||||
components themselves, it's just vanilla CSS because I couldn't figure out how to get Svelte to run a SCSS
 | 
			
		||||
preprocessor.
 | 
			
		||||
 | 
			
		||||
### Lots of small files
 | 
			
		||||
 | 
			
		||||
Highly modular, highly functional, lots of single-function files. Tends to help with tree-shaking and
 | 
			
		||||
code-splitting, as well as avoiding circular dependencies.
 | 
			
		||||
 | 
			
		||||
### Inferno is loaded dynamically
 | 
			
		||||
 | 
			
		||||
This is a Svelte project, but `emoji-mart` is used for the emoji picker, and it's written in React. So we
 | 
			
		||||
lazy-load the React-compatible Inferno library when we load `emoji-mart`.
 | 
			
		||||
 | 
			
		||||
### Some third-party code is bundled
 | 
			
		||||
 | 
			
		||||
For various reasons, `a11y-dialog`, `autosize`, and `timeago` are forked and bundled into the source code.
 | 
			
		||||
This was either because something needed to be tweaked or fixed, or I was trimming unused code and didn't
 | 
			
		||||
see much value in contributing it back, because it was too Pinafore-specific.
 | 
			
		||||
 | 
			
		||||
### Every Sapper page is "duplicated"
 | 
			
		||||
 | 
			
		||||
To get a nice animation on the nav bar when you switch columns, every page is lazy-loaded as `LazyPage.html`.
 | 
			
		||||
This "lazy page" is merely delayed a few frames to let the animation run. Therefore there is a duplication
 | 
			
		||||
between `src/routes` and `src/routes_pages`. The "lazy page" is in the former, and the actual page is in the
 | 
			
		||||
latter. One imports the other.
 | 
			
		||||
 | 
			
		||||
### There are multiple stores
 | 
			
		||||
 | 
			
		||||
Originally I conceived of separating out the virtual list into a separate npm package, so I gave it its
 | 
			
		||||
own Svelte store (`virtualListStore.js`). This never happened, but it still has its own store. This is useful
 | 
			
		||||
anyway, because each store has its state maintained in an LRU cache that allows us to keep the scroll position
 | 
			
		||||
in the virtual list e.g. when the user hits the back button.
 | 
			
		||||
 | 
			
		||||
Also, the main `store.js` store is explicitly
 | 
			
		||||
loaded by every component that uses it. So there's no `store` inheritance; every component just declares
 | 
			
		||||
whatever store it uses. The main `store.js` is the primary one.
 | 
			
		||||
 | 
			
		||||
### There is a global event bus
 | 
			
		||||
 | 
			
		||||
It's in `eventBus.js`. This is useful for some stuff that is hard to do with standard Svelte or DOM events.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue