Skip to content

Commit

Permalink
0.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchambers committed Dec 16, 2012
1 parent eb7e013 commit 4ed60a9
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 122 deletions.
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.PHONY: compile clean release setup test

bin = node_modules/.bin

compile:
@$(bin)/coffee --compile --output lib src

clean:
@rm -rf node_modules
@git checkout -- lib

release:
ifndef VERSION
$(error VERSION is undefined)
endif
@sed -i '' 's!\("version": "\)[0-9.]*\("\)!\1$(VERSION)\2!' package.json
@sed -i '' "s!\(.version = '\)[0-9.]*\('\)!\1$(VERSION)\2!" src/string-format.coffee
@make
@git add package.json src/string-format.coffee lib/string-format.js
@git commit --message $(VERSION)
@echo 'remember to run `npm publish`'

setup:
@npm install

test:
@$(bin)/mocha --compilers coffee:coffee-script
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ greet("Steve", 1)

### Running the test suite

npm install
npm test
make setup
make test


[1]: http://docs.python.org/library/stdtypes.html#str.format
12 changes: 6 additions & 6 deletions string-format.js → lib/string-format.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
{
"name": "string-format",
"version": "0.2.1",
"description": "Adds a `format` method to `String.prototype`. Inspired by Python's `str.format()`.",
"author": "David Chambers <[email protected]>",
"keywords": ["string", "formatting", "language", "util"],
"main": "./lib/string-format",
"homepage": "https://github.com/davidchambers/string-format",
"bugs": "https://github.com/davidchambers/string-format/issues",
"licenses": [{
"type": "WTFPL",
"url": "https://raw.github.com/davidchambers/string-format/master/LICENSE"
}],
"repository": {
"type": "git",
"url": "https://github.com/davidchambers/string-format"
"url": "git://github.com/davidchambers/string-format.git"
},
"author": "David Chambers <[email protected]>",
"main": "string-format.js",
"version": "0.2.0",
"devDependencies": {
"coffee-script": "1.3.x",
"jessie": "0.4.x"
},
"scripts": {
"test": "node_modules/jessie/bin/jessie spec"
"coffee-script": "1.4.x",
"mocha": "1.7.x",
"should": "1.2.x"
}
}
2 changes: 0 additions & 2 deletions spec/spec_helper.js

This file was deleted.

99 changes: 0 additions & 99 deletions spec/stringformat_spec.coffee

This file was deleted.

8 changes: 4 additions & 4 deletions string-format.coffee → src/string-format.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ format = String::format = (args...) ->

idx = 0
explicit = implicit = no
error = 'cannot switch from {} to {} numbering'.format()
message = 'cannot switch from {} to {} numbering'.format()

@replace \
/([{}])\1|[{](.*?)(?:!(.+?))?[}]/g,
Expand All @@ -14,11 +14,11 @@ format = String::format = (args...) ->

if key.length
explicit = yes
throw error('implicit', 'explicit') if implicit
throw new Error message 'implicit', 'explicit' if implicit
value = lookup(args, key) ? ''
else
implicit = yes
throw error('explicit', 'implicit') if explicit
throw new Error message 'explicit', 'implicit' if explicit
value = args[idx++] ? ''

value = value.toString()
Expand All @@ -39,4 +39,4 @@ resolve = (object, key) ->

format.transformers = {}

format.version = '0.2.0'
format.version = '0.2.1'
103 changes: 103 additions & 0 deletions test/string-format.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
assert = require 'assert'
require 'should'

require '../src/string-format'


describe 'String::format', ->

it 'interpolates positional arguments', ->
'{0}, you have {1} unread message{2}'.format('Holly', 2, 's')
.should.equal 'Holly, you have 2 unread messages'

it 'strips unmatched placeholders', ->
'{0}, you have {1} unread message{2}'.format('Steve', 1)
.should.equal 'Steve, you have 1 unread message'

it 'allows indexes to be omitted if they are entirely sequential', ->
'{}, you have {} unread message{}'.format('Steve', 1)
.should.equal 'Steve, you have 1 unread message'

it 'replaces all occurrences of a placeholder', ->
'the meaning of life is {0} ({1} x {2} is also {0})'.format(42, 6, 7)
.should.equal 'the meaning of life is 42 (6 x 7 is also 42)'

it 'creates a reusable template function when invoked with no arguments', ->
explicit = '{0}, you have {1} unread message{2}'.format()
implicit = '{}, you have {} unread message{}'.format()
explicit('Holly', 2, 's').should.equal 'Holly, you have 2 unread messages'
implicit('Holly', 2, 's').should.equal 'Holly, you have 2 unread messages'
explicit('Steve', 1).should.equal 'Steve, you have 1 unread message'
implicit('Steve', 1).should.equal 'Steve, you have 1 unread message'

it 'does not allow explicit and implicit numbering to be intermingled', ->
(-> '{} {0}'.format 'foo', 'bar')
.should.throw 'cannot switch from implicit to explicit numbering'
(-> '{1} {}'.format 'foo', 'bar')
.should.throw 'cannot switch from explicit to implicit numbering'
(-> '{1} {}'.format() 'foo', 'bar')
.should.throw 'cannot switch from explicit to implicit numbering'

it 'treats "{{" and "}}" as "{" and "}"', ->
'{{ {}: "{}" }}'.format('foo', 'bar').should.equal '{ foo: "bar" }'

it 'supports property access via dot notation', ->
bobby = first_name: 'Bobby', last_name: 'Fischer'
garry = first_name: 'Garry', last_name: 'Kasparov'
'{0.first_name} {0.last_name} vs. {1.first_name} {1.last_name}'.format(bobby, garry)
.should.equal 'Bobby Fischer vs. Garry Kasparov'

it 'accepts a shorthand for properties of the first positional argument', ->
bobby = first_name: 'Bobby', last_name: 'Fischer'
'{first_name} {last_name}'.format(bobby).should.equal 'Bobby Fischer'

it 'invokes methods', ->
'{0.toLowerCase}'.format('III').should.equal 'iii'
'{0.toUpperCase}'.format('iii').should.equal 'III'
'{0.getFullYear}'.format(new Date '26 Apr 1984').should.equal '1984'
'{pop}{pop}{pop}'.format(['one', 'two', 'three']).should.equal 'threetwoone'
'{quip.toUpperCase}'.format(quip: -> 'Bazinga!').should.equal 'BAZINGA!'

String::format.transformers.s = -> 's' unless +this is 1

it 'applies transformers to explicit positional arguments', ->
text = '{0}, you have {1} unread message{1!s}'
text.format('Steve', 1).should.equal 'Steve, you have 1 unread message'
text.format('Holly', 2).should.equal 'Holly, you have 2 unread messages'

it 'applies transformers to implicit positional arguments', ->
text = 'The Cure{!s}, The Door{!s}, The Smith{!s}'
text.format(1, 2, 3).should.equal 'The Cure, The Doors, The Smiths'

it 'applies transformers to properties of explicit positional arguments', ->
text = '<a href="/inbox">view message{0.length!s}</a>'
text.format(new Array 1).should.equal '<a href="/inbox">view message</a>'
text.format(new Array 2).should.equal '<a href="/inbox">view messages</a>'

it 'applies transformers to properties of implicit positional arguments', ->
text = '<a href="/inbox">view message{length!s}</a>'
text.format(new Array 1).should.equal '<a href="/inbox">view message</a>'
text.format(new Array 2).should.equal '<a href="/inbox">view messages</a>'

it "passes applicable tests from Python's test suite", ->
''.format(null).should.equal ''
'abc'.format(null).should.equal 'abc'
'{0}'.format('abc').should.equal 'abc'
'X{0}'.format('abc').should.equal 'Xabc'
'{0}X'.format('abc').should.equal 'abcX'
'X{0}Y'.format('abc').should.equal 'XabcY'
'{1}'.format(1, 'abc').should.equal 'abc'
'X{1}'.format(1, 'abc').should.equal 'Xabc'
'{1}X'.format(1, 'abc').should.equal 'abcX'
'X{1}Y'.format(1, 'abc').should.equal 'XabcY'
'{0}'.format(-15).should.equal '-15'
'{0}{1}'.format(-15, 'abc').should.equal '-15abc'
'{0}X{1}'.format(-15, 'abc').should.equal '-15Xabc'
'{{'.format(null).should.equal '{'
'}}'.format(null).should.equal '}'
'{{}}'.format(null).should.equal '{}'
'{{x}}'.format(null).should.equal '{x}'
'{{{0}}}'.format(123).should.equal '{123}'
'{{{{0}}}}'.format(null).should.equal '{{0}}'
'}}{{'.format(null).should.equal '}{'
'}}x{{'.format(null).should.equal '}x{'

0 comments on commit 4ed60a9

Please sign in to comment.