Skip to content

Commit 8f2df11

Browse files
committed
Merge remote-tracking branch 'source/master' into master
2 parents 6bfb71b + c692486 commit 8f2df11

File tree

17 files changed

+110
-54
lines changed

17 files changed

+110
-54
lines changed

.flake8

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
[flake8]
3+
max-line-length = 100
4+
ignore = E501,W503
5+
exclude = .git,__pycache__,docs/source/conf.py,build,dist,venv,node_modules,.tox,scaffolds

.github/workflows/build.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Running unittests
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
unittests:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: [3.6, 3.9]
15+
django: ["2.2", "3.1"]
16+
17+
steps:
18+
- uses: actions/checkout@v2
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v2
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install -r requirements_test.txt
27+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28+
- name: Linting
29+
run: flake8
30+
- name: Run unittests
31+
env:
32+
TOX_ENV: py${{ matrix.python-version}}-django${{ matrix.django }}
33+
run: |
34+
tox -e $TOX_ENV
35+
integrationtests:
36+
runs-on: ubuntu-latest
37+
steps:
38+
- uses: actions/checkout@v2
39+
- name: Set up Python 3.x
40+
uses: actions/setup-python@v2
41+
with:
42+
python-version: '3.9'
43+
- name: Install dependencies
44+
run: |
45+
python -m pip install --upgrade pip
46+
pip install -r requirements_test.txt
47+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
48+
- name: Run integration tests
49+
env:
50+
TOX_ENV: py3.9-django3.1-cypress
51+
run: |
52+
tox -e $TOX_ENV

.travis.yml

Lines changed: 0 additions & 22 deletions
This file was deleted.

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ python manage.py runserver
8383
# visit https://localhost:8000/test
8484
```
8585

86+
## ⛑ Running tests locally
87+
The most important tests are integration tests that makes sure that frontend and backend work together in conjunction with each other.
88+
89+
```
90+
# Install the cypress et al
91+
npm install
92+
93+
# Spin up a dev server.
94+
python manage.py runserver
95+
96+
# Run the cypress tests
97+
npm run cypress:run
98+
```
99+
100+
86101
## 🔜 Release
87102

88103
```

docs/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,12 @@ Also, we just really enjoy using **Django**.
5353

5454
Sockpuppet was originally inspired by StimulusReflex which was inspired by LiveView, but we are charting our own course together with StimulusReflex. Our goal has always been to make building modern apps with Django the most productive and enjoyable option available. We want to inspire our friends working with other tools and technologies to evaluate how concepts like Sockpuppet could work in their ecosystems and communities.
5555

56+
## Architecture
57+
58+
So what is happening behind the scenes here? Sockpuppet works in three layers.
59+
60+
It uses javascript; The javascript is re-used from StimulusReflex, which in itself is built upon stimulusjs. The javascript in StimulusReflex also uses something called cable_ready which has the responsibility of modifying the DOM. The javascript layer ensures that the data is being sent to the server layer through websockets. When a message is received from the server layer it will re-render the dom according to the server side instructions.
61+
62+
The HTML layer has the responsibility of defining where and how a "reflex" is going to be triggered. Ie, a reflex could be triggered by an browser event or the click of a button. When building more complex applications the HTML layer may also be used to store state so that this state is accessible when doing some interactivity in a stimulus controller.
63+
64+
The last layer is server layer. This is where a "Reflex" class is defined. The reflex knows what path and template was received and will re-render that template to contain any new information defined in the reflex. The reflex could also make database queries and such as well. Once the template is re-rendered it will send it back to frontend where javascript will modify the DOM to update everything.

docs/setup-django.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,11 @@ The configuration above will look for javascript files in the folder `your_app/j
133133

134134
If you add that folder to `STATICFILES_DIRS` in settings it will pick that compiled javascript and you can use it in templates.
135135

136-
```text
136+
```python
137+
from pathlib import Path
138+
BASE_DIR = Path.cwd()
137139
STATICFILES_DIRS = [
138-
("js", "/dist/js"),
140+
("js", f"{BASE_DIR}/dist/js"),
139141
]
140142
```
141143

sockpuppet/management/commands/generate_reflex.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
from pathlib import Path
22

3-
from django.apps import apps
4-
from django.core.management.base import BaseCommand, CommandError
53
from django.template.loader import get_template
64

75
from ._base import BaseGenerateCommand
8-
6+
from ...utils import classify
97

108
TEMPLATES = {
119
'_reflex.py': 'sockpuppet/scaffolds/reflex.py',
@@ -48,8 +46,8 @@ def handle(self, *args, **options):
4846
for path, suffix in paths:
4947
template_name = TEMPLATES[suffix]
5048
template = get_template(template_name)
51-
rendered = template.render({'reflex_name': reflex_name})
52-
self.create_file(path, '{}{}'.format(reflex_name, suffix), rendered)
49+
rendered = template.render({'class_name': classify(reflex_name), 'reflex_name': reflex_name})
50+
self.create_file(path, '{}{}'.format(reflex_name.lower(), suffix), rendered)
5351

5452
self.create_file('views', '__init__.py', '')
5553
self.create_file('reflexes', '__init__.py', '')

sockpuppet/templates/sockpuppet/scaffolds/application.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Application } from 'stimulus'
22
import StimulusReflex from 'stimulus_reflex'
33
import WebsocketConsumer from 'sockpuppet-js'
4-
import {{reflex_name|title }}Controller from './controllers/{{reflex_name}}_controller'
4+
import {{ reflex_name|title }}Controller from './controllers/{{ reflex_name|lower }}_controller'
55

66
const application = Application.start()
77
const consumer = new WebsocketConsumer('ws://localhost:8000/ws/sockpuppet-sync')

sockpuppet/templates/sockpuppet/scaffolds/controller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ export default class extends Controller {
99
increment(event) {
1010
console.log('increment')
1111
event.preventDefault()
12-
this.stimulate('{{ reflex_name|title }}Reflex#increment', 1)
12+
this.stimulate('{{ reflex_name }}Reflex#increment', 1)
1313
}
1414
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from sockpuppet.reflex import Reflex
22

33

4-
class {{ reflex_name|title }}Reflex(Reflex):
4+
class {{ class_name }}Reflex(Reflex):
55
def increment(self, step=1):
66
self.count = int(self.element.dataset['count']) + step

0 commit comments

Comments
 (0)