Last active
September 12, 2018 04:15
-
-
Save magistrula/221ff7e041bca9f602a6f846b1756686 to your computer and use it in GitHub Desktop.
Build-a-Face
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
const { computed } = Ember; | |
export const FACE_COLOR_OPTIONS = [ | |
{ value: 'salmon', label: 'red' }, | |
{ value: 'orange', label: 'orange' }, | |
{ value: 'yellow', label: 'yellow' }, | |
{ value: 'palegreen', label: 'green' }, | |
{ value: 'lightblue', label: 'blue' }, | |
{ value: 'lavender', label: 'purple', isDefault: true }, | |
{ value: 'pink', label: 'pink' }, | |
{ value: 'lightgray', label: 'gray' } | |
]; | |
export const HAT_COLOR_OPTIONS = [ | |
{ value: 'crimson', label: 'red' }, | |
{ value: 'orangered', label: 'orange' }, | |
{ value: 'gold', label: 'yellow' }, | |
{ value: 'mediumspringgreen', label: 'green' }, | |
{ value: 'dodgerblue', label: 'blue', isDefault: true }, | |
{ value: 'blueviolet', label: 'purple' }, | |
{ value: 'fuchsia', label: 'pink' }, | |
{ value: 'saddlebrown', label: 'brown' }, | |
{ value: 'gray', label: 'gray' } | |
]; | |
export default Ember.Component.extend({ | |
classNames: ['MyFace'], | |
// This would normally be handled by ember-get-component | |
attributeBindings: ['data-test-component-name'], | |
['data-test-component-name']: 'my-face', | |
// internal params | |
faceColorOptions: null, | |
hatColorOptions: null, | |
eyeContent: null, | |
noseContent: null, | |
mouthContent: null, | |
faceColor: null, | |
hatColor: null, | |
pathToMessage: null, | |
noseMessage: 'I love to stop and smell the roses.', | |
mouthMessage: 'Feed me!', | |
leftEyeMessage: '<wink wink>', | |
rightEyeMessage: computed('activeFaceColorOption', function() { | |
const faceColorLabel = this.get('activeFaceColorOption.label'); | |
return `I spy with my little eye something ${faceColorLabel}.`; | |
}), | |
message: computed('pathToMessage', 'activeFaceColorOption', function() { | |
const pathToMessage = this.get('pathToMessage'); | |
return pathToMessage ? | |
this.get(pathToMessage) : | |
'(Click my eyes, nose, or mouth to see a special message)'; | |
}), | |
isFaceComplete: computed.and('eyeContent', 'noseContent', 'mouthContent'), | |
faceStyle: computed('activeFaceColorOption', 'activeHatColorOption', function() { | |
const faceColor = this.get('activeFaceColorOption.value'); | |
const hatColor = this.get('activeHatColorOption.value'); | |
return Ember.String.htmlSafe( | |
`background-color: ${faceColor}; border-color: ${hatColor}` | |
); | |
}), | |
init() { | |
this._super(...arguments); | |
this._resetFace(); | |
}, | |
_resetFace() { | |
this.setProperties({ | |
eyeContent: '**', | |
noseContent: '~~', | |
mouthContent: '\\=======/', | |
faceColorOptions: FACE_COLOR_OPTIONS, | |
hatColorOptions: HAT_COLOR_OPTIONS, | |
activeFaceColorOption: FACE_COLOR_OPTIONS.findBy('isDefault'), | |
activeHatColorOption: HAT_COLOR_OPTIONS.findBy('isDefault'), | |
pathToMessage: null | |
}); | |
}, | |
actions: { | |
setFaceColor(colorOption) { | |
this.set('activeFaceColorOption', colorOption); | |
}, | |
setHatColor(colorOption) { | |
this.set('activeHatColorOption', colorOption); | |
}, | |
showLeftEyeMessage() { | |
if (this.get('isFaceComplete')) { | |
this.set('pathToMessage', 'leftEyeMessage'); | |
} | |
}, | |
showRightEyeMessage() { | |
if (this.get('isFaceComplete')) { | |
this.set('pathToMessage', 'rightEyeMessage'); | |
} | |
}, | |
showNoseMessage() { | |
if (this.get('isFaceComplete')) { | |
this.set('pathToMessage', 'noseMessage'); | |
} | |
}, | |
showMouthMessage() { | |
if (this.get('isFaceComplete')) { | |
this.set('pathToMessage', 'mouthMessage'); | |
} | |
}, | |
clearFace() { | |
this._resetFace(); | |
} | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
export default Ember.Component.extend({ | |
classNames: ['MyFaceMyEyes'], | |
// This would normally be handled by ember-get-component | |
attributeBindings: ['data-test-component-name'], | |
['data-test-component-name']: 'my-face/my-eyes', | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
export default Ember.Component.extend({ | |
classNames: ['MyFaceMyMouth'] | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
export default Ember.Component.extend({ | |
classNames: ['MyFaceMyNose'] | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
export default Ember.Controller.extend({ | |
appName: 'Build-a-Face' | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
margin: 12px 16px; | |
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
font-size: 12pt; | |
} | |
.u-space-below { | |
margin-bottom: 15px; | |
} | |
.u-more-space-below { | |
margin-bottom: 20px; | |
} | |
.u-clickable { | |
cursor: pointer; | |
} | |
.MyFace { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
} | |
.MyFace-face { | |
width: 200px; | |
height: 150px; | |
padding-top: 10px; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
border-radius: 50%; | |
border-top: 60px solid; | |
border-left: 4px solid; | |
border-right: 4px solid; | |
} | |
.MyFace-message { | |
height: 1em; | |
margin-bottom: 30px; | |
color: darkslategray; | |
font-style: italic; | |
} | |
.MyFace-buttonCategory { | |
margin-right: 5px; | |
font-size: .8em; | |
font-weight: bold; | |
} | |
.MyFace-colorButton.is-active { | |
color: navy; | |
font-weight: bold; | |
} | |
.MyFaceMyEyes { | |
width: 150px; | |
height: 1em; | |
display: flex; | |
justify-content: space-around; | |
color: blue; | |
} | |
.MyFaceMyNose { | |
height: 1em; | |
color: green; | |
} | |
.MyFaceMyMouth { | |
height: 1em; | |
color: red; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { run } from '@ember/runloop'; | |
export default function destroyApp(application) { | |
run(application, 'destroy'); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Resolver from '../../resolver'; | |
import config from '../../config/environment'; | |
const resolver = Resolver.create(); | |
resolver.namespace = { | |
modulePrefix: config.modulePrefix, | |
podModulePrefix: config.podModulePrefix | |
}; | |
export default resolver; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
import Application from '../../app'; | |
import config from '../../config/environment'; | |
const { run } = Ember; | |
const assign = Ember.assign || Ember.merge; | |
export default function startApp(attrs) { | |
let application; | |
let attributes = assign({rootElement: "#test-root"}, config.APP); | |
attributes = assign(attributes, attrs); // use defaults, but you can override; | |
run(() => { | |
application = Application.create(attributes); | |
application.setupForTesting(); | |
application.injectTestHelpers(); | |
}); | |
return application; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { moduleForComponent, test } from 'ember-qunit'; | |
import hbs from 'htmlbars-inline-precompile'; | |
import { | |
FACE_COLOR_OPTIONS, | |
HAIR_COLOR_OPTIONS | |
} from 'app/components/my-face'; | |
import { | |
attribute, | |
collection, | |
create, | |
fillable, | |
hasClass, | |
text | |
} from 'ember-cli-page-object'; | |
import { alias, getter } from 'ember-cli-page-object/macros'; | |
// -- PAGE OBJECT (START) -- | |
const SELECTORS = { | |
COMPONENT: '[data-test-component-name="my-face"]', | |
EYES: '[data-test-component-name="my-face/my-eyes"]', | |
EYES_LEFT: '[data-test-left-eye]', | |
EYES_RIGHT: '[data-test-left-eye]', | |
EYES_INPUT: '[data-test-attr="MyFace-eyesInput"]', | |
FACE_COLOR_BUTTON: '[data-test-face-color-button]', | |
FACE_CONTENT: '[data-test-face-content]', | |
}; | |
const MyFace = { | |
scope: SELECTORS.COMPONENT, // SCOPE | |
// pretend this eyes component is so complicated that it needs its own page object, | |
// which we would define in a separate file then import for use in this PO | |
eyes: { | |
scope: SELECTORS.EYES, // SCOPE | |
leftEyeText: text(SELECTORS.EYES_LEFT), | |
rightEyeText: text(SELECTORS.EYES_RIGHT), | |
hasSameTextForBothEyes: getter(function() { // GETTER | |
return this.leftEyeText === this.rightEyeText; | |
}), | |
}, | |
eyesText: alias('eyes.leftEyeText'), // ALIAS | |
setEyesText: fillable(SELECTORS.EYES_INPUT), | |
faceStyle: attribute('style', SELECTORS.FACE_CONTENT), | |
faceColorButtons: collection({ // COLLECTION | |
itemScope: SELECTORS.FACE_COLOR_BUTTON, // SCOPE | |
item: { | |
isActive: hasClass('is-active') | |
} | |
}) | |
}; | |
const PO = create(MyFace); | |
// -- PAGE OBJECT (END) -- | |
moduleForComponent('my-face', 'MyFaceComponent', { | |
integration: true, | |
beforeEach() { | |
PO.setContext(this); | |
}, | |
afterEach() { | |
PO.removeContext(); | |
} | |
}); | |
test('starts out with default eye content', function(assert) { | |
this.render(hbs`{{my-face}}`); | |
assert.equal(PO.eyesText, '**'); | |
}); | |
test('can set the eyes content', function(assert) { | |
this.render(hbs`{{my-face}}`); | |
PO.setEyesText('!-!'); | |
assert.equal(PO.eyesText, '!-!'); | |
}); | |
test('shows the expected # of face color buttons', function(assert) { | |
this.render(hbs`{{my-face}}`); | |
assert.equal(PO.faceColorButtons().count, FACE_COLOR_OPTIONS.length); | |
}); | |
test('shows a user-facing label for each face color button', function(assert) { | |
this.render(hbs`{{my-face}}`); | |
FACE_COLOR_OPTIONS.forEach((option, index) => { | |
assert.equal(PO.faceColorButtons(index).text, FACE_COLOR_OPTIONS[index].label); | |
}); | |
}); | |
test('can set the face color', function(assert) { | |
this.render(hbs`{{my-face}}`); | |
PO.faceColorButtons(0).click(); | |
const expectedStyling = `background-color: ${FACE_COLOR_OPTIONS[0].value}`; | |
assert.ok(PO.faceStyle.includes(expectedStyling)); | |
}); | |
test('styles the currently selected face color button', function(assert) { | |
this.render(hbs`{{my-face}}`); | |
PO.faceColorButtons(0).click(); | |
assert.equal(false, true); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import resolver from './helpers/resolver'; | |
import { | |
setResolver | |
} from 'ember-qunit'; | |
import { start } from 'ember-cli-qunit'; | |
setResolver(resolver); | |
start(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": "0.15.0", | |
"EmberENV": { | |
"FEATURES": {} | |
}, | |
"options": { | |
"use_pods": false, | |
"enable-testing": false | |
}, | |
"dependencies": { | |
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js", | |
"ember": "3.2.2", | |
"ember-template-compiler": "3.2.2", | |
"ember-testing": "3.2.2" | |
}, | |
"addons": { | |
"ember-data": "2.12.2", | |
"ember-cli-page-object": "1.13.0", | |
"ember-test-selectors": "1.0.0", | |
"ember-truth-helpers": "1.2.0" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment