-
-
Save maca/206fdce951e50c6f4ef8 to your computer and use it in GitHub Desktop.
This file contains 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
class Scope extends Spine.Module | |
constructor: (@parent, Negate, @positive, @lambda, @params) -> | |
@not = new Negate(@) | |
all: -> | |
keep = (record) => | |
result = @lambda.apply(record, @params) | |
if @positive then result else not result | |
record for record in @parent.all() when keep(record) | |
class Negate extends Spine.Module | |
constructor: (@parent) -> | |
Spine.Model.extend | |
scopes: (scopes) -> | |
ScopeSub = @Scope or= Scope.sub() | |
NegateSub = @Negate or= Negate.sub() | |
@not = {} | |
for key, lambda of scopes | |
do (lambda) => | |
@[key] = ScopeSub::[key] = -> new ScopeSub(@, NegateSub, true, lambda, arguments) | |
@not[key] = => new ScopeSub(@, NegateSub, false, lambda, arguments) | |
NegateSub::[key] = -> new ScopeSub(@parent, NegateSub, false, lambda, arguments) | |
sorts: (sorts) -> | |
ScopeSub = @Scope or= Scope.sub() | |
for key, lambda of sorts | |
do (lambda) => | |
@[key] = ScopeSub::[key] = -> @.all().sort(lambda) |
This file contains 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
class Person extends Spine.Model | |
@configure 'Person', 'name' | |
@scopes | |
startsWith: (char) -> @name[0] is char | |
endsWith: (char) -> @name[@name.length - 1] is char | |
@sorts | |
byName: (a, b) -> | |
if a.name > b.name then 1 else -1 | |
class Dummy extends Spine.Model | |
@configure 'Dummy' | |
@scopes dummy: -> true | |
describe 'Scopes', -> | |
afterEach -> | |
Person.destroyAll() | |
beforeEach -> | |
@matias = Person.create(name: 'Matías') | |
@beto = Person.create(name: 'Beto') | |
@macario = Person.create(name: 'Macario') | |
it 'generates scope functions', -> | |
expect(typeof Person.startsWith).toBe 'function' | |
expect(typeof Person.endsWith).toBe 'function' | |
it 'scopes', -> | |
scope = Person.startsWith('M') | |
names = ( person.name for person in scope.all() ) | |
expect( names.length ).toBe 2 | |
expect( names.indexOf('Macario') ).toBeGreaterThan -1 | |
expect( names.indexOf('Matías') ).toBeGreaterThan -1 | |
scope = Person.endsWith('o') | |
names = ( person.name for person in scope.all() ) | |
expect( names.length ).toBe 2 | |
expect( names.indexOf('Macario') ).toBeGreaterThan -1 | |
expect( names.indexOf('Beto') ).toBeGreaterThan -1 | |
it 'extends model scope class', -> | |
scope = Person.startsWith() | |
expect(typeof scope.startsWith).toBe 'function' | |
expect(typeof scope.endsWith).toBe 'function' | |
scope = Person.endsWith() | |
expect(typeof scope.startsWith).toBe 'function' | |
expect(typeof scope.endsWith).toBe 'function' | |
it 'doesnt contaminate other model scopes', -> | |
scope = Dummy.dummy() | |
expect(scope.startsWith).toBe undefined | |
expect(Dummy.startsWith).toBe undefined | |
it 'concatenates scopes', -> | |
scope = Person.startsWith('M').endsWith('o') | |
names = ( person.name for person in scope.all() ) | |
expect( names.length ).toBe 1 | |
expect( names.indexOf('Macario') ).toBeGreaterThan -1 | |
it 'negates scope', -> | |
scope = Person.not.startsWith('M') | |
names = ( person.name for person in scope.all() ) | |
expect( names.length ).toBe 1 | |
expect( names.indexOf('Beto') ).toBeGreaterThan -1 | |
it 'negates concatenated scopes', -> | |
scope = Person.startsWith('M').not.endsWith('o') | |
names = ( person.name for person in scope.all() ) | |
expect( names.length ).toBe 1 | |
expect( names.indexOf('Matías') ).toBeGreaterThan -1 | |
it 'double negates concatenated scopes', -> | |
scope = Person.not.startsWith('B').not.endsWith('o') | |
names = ( person.name for person in scope.all() ) | |
expect( names.length ).toBe 1 | |
expect( names.indexOf('Matías') ).toBeGreaterThan -1 | |
it 'doesnt contaminate other Negate classes', -> | |
scope = Dummy.dummy() | |
expect(scope.not.startsWith).toBe undefined | |
expect(Dummy.not.startsWith).toBe undefined | |
it 'sorts', -> | |
names = ( person.name for person in Person.byName() ) | |
expect( names ).toEqual ['Beto', 'Macario', 'Matías'] | |
it 'sorts when scoped', -> | |
scope = Person.startsWith('M') | |
names = ( person.name for person in scope.byName() ) | |
expect( names ).toEqual ['Macario', 'Matías'] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment