Skip to content

Add --coffee option to component generator #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 29, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,14 @@ For example:
rails generate react:component Label label:string --es6
```

**--coffee** : Generate the component using CoffeeScript syntax

For example:

```shell
rails generate react:component Label label:string --coffee
```

#### Arguments

The generator can use the following arguments to create basic propTypes:
Expand Down
21 changes: 17 additions & 4 deletions lib/generators/react/component_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ class ComponentGenerator < ::Rails::Generators::NamedBase
:banner => "field[:type] field[:type] ..."

class_option :es6,
type: :boolean,
default: false,
desc: 'Output es6 class based component'
type: :boolean,
default: false,
desc: 'Output es6 class based component'

class_option :coffee,
type: :boolean,
default: false,
desc: 'Output coffeescript based component'

REACT_PROP_TYPES = {
"node" => 'React.PropTypes.node',
Expand Down Expand Up @@ -85,7 +90,15 @@ class ComponentGenerator < ::Rails::Generators::NamedBase
}

def create_component_file
extension = options[:es6] ? "es6.jsx" : "js.jsx"
extension = case
when options[:es6]
'es6.jsx'
when options[:coffee]
'js.jsx.coffee'
else
'js.jsx'
end

file_path = File.join('app/assets/javascripts/components', "#{file_name}.#{extension}")
template("component.#{extension}", file_path)
end
Expand Down
18 changes: 18 additions & 0 deletions lib/generators/templates/component.js.jsx.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class @<%= file_name.camelize %> extends React.Component
<% if attributes.size > 0 -%>
@propTypes =
<% attributes.each do |attribute| -%>
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:type] %>
<% end -%>

<% end -%>
render: ->
<% if attributes.size > 0 -%>
`<div>
<% attributes.each do |attribute| -%>
<div><%= attribute[:name].titleize %>: {this.props.<%= attribute[:name].camelize(:lower) %>}</div>
<% end -%>
</div>`
<% else -%>
`<div />`
<% end -%>
40 changes: 40 additions & 0 deletions test/generators/coffee_component_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'test_helper'
require 'generators/react/component_generator'

class CoffeeComponentGeneratorTest < Rails::Generators::TestCase
destination File.join(Rails.root, 'tmp', 'component_generator_test_output')
setup :prepare_destination
tests React::Generators::ComponentGenerator

def filename
'app/assets/javascripts/components/generated_component.js.jsx.coffee'
end

def class_name
'GeneratedComponent'
end

test 'that it the uses CoffeeScript syntax' do
run_generator %w(GeneratedComponent name --coffee)

assert_file filename, /^class @#{class_name}\sextends\sReact\.Component/
end

test 'that propTypes get assigned' do
run_generator %w(GeneratedComponent name --coffee)

assert_file filename, /@propTypes\s=/
assert_file filename, /React.PropTypes/
end

test 'that it generates working jsx' do
expected_name_div = /React\.createElement\(\s*"div",\s*null,\s*"Name:\s*",\s*this\.props\.name\s*\)/x
expected_shape_div = /React\.createElement\(\s*"div",\s*null,\s*"Address:\s*",\s*this\.props\.address\s*\)/x

run_generator %w(GeneratedComponent name:string address:shape --coffee)
jsx = React::JSX.transform(CoffeeScript.compile(File.read(File.join(destination_root, filename))))

assert_match(Regexp.new(expected_name_div), jsx)
assert_match(Regexp.new(expected_shape_div), jsx)
end
end